Если вы разрабатывали приложение с использованием AngularJS, вы, вероятно, знаете об HTTP-перехватчиках. Однако эти HTTP-перехватчики появились в Angular только в версии 4.3. В этом руководстве мы будем использовать перехватчики в Angular для обработки HTTP-запросов и ответов, а также для обработки ошибок.
Предварительные требования
Angular приложения используют Node.js среду выполнения. Для выполнения этого руководства вам понадобится установленный Node.js на вашем компьютере. К счастью, Node.js довольно легко установить. У нас есть полное руководство по теме Как установить Node.js on Ubuntu 18.04 здесь.
Кроме того, вам будет полезно знать Angular и уметь использовать Angular CLI для создания приложений Angular. Мы будем использовать Node v8.12.0 и npm v6.4.1.
Шаг 1: Создание приложения Angular
Для начала давайте создадим новое приложение Angular с помощью Angular CLI. Мы назовем наше приложение Angular-Interceptor. Запустите команду ниже, чтобы создать приложение:
|
1 |
npx @angular/cli@7.0.6 new Angular-Interceptor |
Вам будет предложено сделать выбор. Введите значения по умолчанию и продолжайте:

Затем перейдите в каталог приложения и запустите команду ниже, чтобы запустить приложение:
|
1 |
npx ng serve --open |

Затем откройте http://localhost:4200 в вашем браузере, чтобы увидеть приложение. Теперь вы настроили базовое приложение Angular.
Шаг 2: Стилизация приложения Angular
Здесь мы будем стилизовать наше приложение Angular с помощью Angular Material. Чтобы установить Angular Material в ваш проект, запустите команду ниже:
|
1 |
npm install --save @angular/material@7.0.4 @angular/cdk@7.0.4 @angular/animations@7.0.4 |
Это установит @angular/material, @angular/cdk, и @angular/animation в ваш проект. Далее мы настроим анимацию в проекте. Добавьте BrowserAnimationsModule в ваш src/app/module.ts файл:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
... import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; @NgModule({ ... imports: [ ... BrowserAnimationsModule ], ... }) export class AppModule { } |
Мы будем использовать компонент Dialog из Angular Material. Чтобы использовать компонент Dialog, нам нужно импортировать MatDialogModule в src/app/app.module.ts файл:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
... import { MatDialogModule } from '@angular/material'; @NgModule({ ... imports: [ ... MatDialogModule ], ... }) export class AppModule { } |
Чтобы сделать интерфейс более привлекательным, давайте добавим indigo-pink.css в ваш styles.scss файл:
|
1 |
@import "~@angular/material/prebuilt-themes/indigo-pink.css"; |
Шаг 3: Создание вашего Angular-перехватчика
В папке app мы создадим новую папку с именем interceptor. Внутри этой созданной папки создайте новый httpconfig.interceptor.ts файл.
Нам нужно импортировать некоторые зависимости в наш httpconfig.interceptor.ts, чтобы наш перехватчик работал. Этими зависимостями являются HttpInterceptor, HttpRequest, HttpResponse, и HttpHandler, HttpEvent, HttpErrorResponse.
Наш httpconfig.interceptor.ts файл после импорта будет выглядеть следующим образом:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
import { Injectable } from '@angular/core'; import { HttpInterceptor, HttpRequest, HttpResponse, HttpHandler, HttpEvent, HttpErrorResponse } from '@angular/common/http'; import { Observable, throwError } from 'rxjs'; import { map, catchError } from 'rxjs/operators'; |
Затем создайте класс HttpConfigInterceptor и реализуйте интерфейс HttpInterceptor. Вот пример:
|
1 2 3 4 5 6 7 |
@Injectable() export class HttpConfigInterceptor implements HttpInterceptor { intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { // ... } } |
Добавьте приведенный ниже код в httpconfig.interceptor.ts файл:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
... @Injectable() export class HttpConfigInterceptor implements HttpInterceptor { intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { const token: string = localStorage.getItem('token'); if (token) { request = request.clone({ headers: request.headers.set('Authorization', 'Bearer ' + token) }); } if (!request.headers.has('Content-Type')) { request = request.clone({ headers: request.headers.set('Content-Type', 'application/json') }); } request = request.clone({ headers: request.headers.set('Accept', 'application/json') }); return next.handle(request).pipe( map((event: HttpEvent<any>) => { if (event instanceof HttpResponse) { console.log('event--->>>', event); } return event; })); } } |
Чтобы это заработало, нам нужно импортировать httpconfig.interceptor.ts в наш app.module.ts файл:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
... import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http'; ... import { HttpConfigInterceptor } from './interceptor/httpconfig.interceptor'; @NgModule({ ... imports: [ ... HttpClientModule ], ... }) |
Добавьте HttpConfigInterceptor в providers. Мы установим multi: true для обработки нескольких перехватчиков:
|
1 2 3 4 5 6 7 8 9 10 |
... @NgModule({ ... providers: [ ... { provide: HTTP_INTERCEPTORS, useClass: HttpConfigInterceptor, multi: true } ], ... }) ... |
В следующем разделе мы создадим наш сервис для обработки ошибок.
Шаг 4: Сервис для обработки ошибок
Здесь мы будем писать код для обработки ошибок. Нам нужно будет перехватывать ошибки и соответствующим образом отображать их конечным пользователям. В двух словах, ниже описаны шаги, которым мы будем следовать:
- Создайте папку с именем error-dialog в app папке.
- Создайте сервис для ошибок с именем errorDialogService в файле с именем errordialog.service.ts.
- Добавьте приведенный ниже код в errordialog.service.ts :
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
import { Injectable } from '@angular/core'; import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material'; import { ErrorDialogComponent } from './errordialog.component'; @Injectable() export class ErrorDialogService { public isDialogOpen: Boolean = false; constructor(public dialog: MatDialog) { } openDialog(data): any { if (this.isDialogOpen) { return false; } this.isDialogOpen = true; const dialogRef = this.dialog.open(ErrorDialogComponent, { width: '300px', data: data }); dialogRef.afterClosed().subscribe(result => { console.log('Диалоговое окно было закрыто'); this.isDialogOpen = false; let animal; animal = result; }); } } |
|
1 2 3 4 5 6 7 8 9 10 11 12 |
import { Component, Inject } from '@angular/core'; import { MAT_DIALOG_DATA } from '@angular/material'; @Component({ selector: 'app-root', templateUrl: './errordialog.component.html' }) export class ErrorDialogComponent { title = 'Angular-Interceptor'; constructor(@Inject(MAT_DIALOG_DATA) public data: string) {} } |
|
1 2 3 4 5 6 7 8 9 10 |
<div> <div> <p> Причина: {{data.reason}} </p> <p> Статус: {{data.status}} </p> </div> </div> |
Подводя итог, перечислим шаги ниже:
- Начните с импорта errordialog.service.
- Затем мы добавим конструктор для errorDialogService.
- Мы также добавим код для обработки ответа об ошибке с помощью catchError и throwError.
- Импортируйте errordialog.service и errordialog.component в AppModule.
После внесения изменений будут изменены два файла: app.module.ts и httpconfig.interceptor.ts:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
... import { ErrorDialogComponent } from './error-dialog/errordialog.component'; ... import { ErrorDialogService } from './error-dialog/errordialog.service'; ... @NgModule({ ... declarations: [ ... ErrorDialogComponent ], ... providers: [ ... ErrorDialogService ], entryComponents: [ErrorDialogComponent], }) |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
... import { ErrorDialogService } from '../error-dialog/errordialog.service'; ... @Injectable() export class HttpConfigInterceptor implements HttpInterceptor { constructor(public errorDialogService: ErrorDialogService) { } intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { ... return next.handle(request).pipe( map((event: HttpEvent<any>) => { if (event instanceof HttpResponse) { console.log('event--->>>', event); } return event; }), catchError((error: HttpErrorResponse) => { let data = {}; data = { reason: error && error.error && error.error.reason ? error.error.reason : '', status: error.status }; this.errorDialogService.openDialog(data); return throwError(error); })); } } |
Шаг 5. Создание демонстрационных сервисов
На этом шаге мы создадим два сервиса в качестве примера:
- Login API
- Customer Detail API
Создайте новую папку с именем services в папке src . Затем внутри этой только что созданной папки создайте новый файл с именем login.service.ts, и добавьте две функции:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; @Injectable() export class LoginService { constructor(private http: HttpClient) { } login(data) { data = { email: 'admin', password: 'admin' }; return this.http.post('http://localhost:3070/api/login', data); } getCustomerDetails() { return this.http.get('http://localhost:3070/customers/details'); } } |
Шаг 6. Вызов службы HTTP-клиента
Наконец, мы подошли к последней части нашего руководства. Мы будем вызывать нашу HTTP-службу из файла app.component.ts. Добавьте две функции LoginService в app.component.ts. Вызовите API login при onload, а customers/details — при onclick:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
import { Component } from '@angular/core'; import { LoginService } from './services/login.service'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.scss'] }) export class AppComponent { title = 'Angular-Interceptor'; constructor(public loginService: LoginService) { this.loginService.login({}).subscribe(data => { console.log(data); }); } getCustomerDetails() { this.loginService.getCustomerDetails().subscribe((data) => { console.log('----->>>', data); }); } } |
Now we have to add a UI element in app.component.html, so that the user can click it:
|
1 |
<h2 (click)="getCustomerDetails()">Получить данные клиента</h2> |
Чтобы завершить, вам потребуется включить LoginService в providers в AppModule:
|
1 2 3 4 5 6 7 8 9 10 11 12 |
... import { LoginService } from './services/login.service'; ... @NgModule({ ... providers: [ ... LoginService ] ... }) |
Ниже представлен скриншот диалогового окна обработчика ошибок:

Заключение
В этом руководстве мы узнали, как обрабатывать HTTP-запросы и ответы с помощью интерцепторов Angular. Мы также узнали, как обрабатывать ошибки с помощью диалогового окна в Angular Material.
Приложения Angular используют Node.js в качестве среды выполнения. Если вы хотите узнать больше о Node.js и о том, как развертывать приложения Node.js с помощью Docker, ознакомьтесь с нашим руководством Как развернуть приложение Node.js (Express.js) с помощью Docker на Ubuntu 20.04. Вы также можете ознакомиться с Как выполнять производственные задачи на Ubuntu 20.04 с помощью Node.js и Установка Node.js на CentOS 8: полное руководство.
Приятной работы!
Комментарии
Комментариев пока нет. Будьте первым.