Angular 6 & 7 HTTP Client Interceptor с обработкой ошибок

Angular 6 & 7 HTTP Client Interceptor с обработкой ошибок

Программный код

В данном руководстве объясняется, как в Angular 6 и 7 при помощи интерцепторов(перехватчиков) обрабатывать HTTP-запросы и ответы .

Ресурсы

Нам понадобиться node.js 8.12.0 и npm v6.4.1, а также Angular CLI.

$ npm install -g angular-cli

Вам также надо иметь общее представление о создании приложений при помощи Angular CLI.

Создание приложения

Для создания приложения в CLI выполните следующие команды:

$ ng new Angular-Interceptor $ cd Angular-Interceptor$ ng serve

После этого открываем в браузере ссылку http://localhost:4200 и добавляем компонент material в Angular-приложение. Он нужен для улучшения работы пользовательского интерфейса. Подробное описание установки компонента можно найти здесь.

Шаг 1: Установка Angular Material, Angular CDK и Angular Animations

Выполните следующие команды:

npm install --save @angular/material @angular/cdk @angular/animations

Шаг 2: Параметр анимации

Импортируйте BrowserAnimationsModule в AppModule

import {BrowserAnimationsModule} from '@angular/platform-browser/animations';@NgModule({... imports: [BrowserAnimationsModule],...})export class AppModule { }

Шаг 3: Импортирование модулей компонентов

Импортируем MatDialogModule в модуль AppModule.

import { MatDialogModule } from '@angular/material';@NgModule({ imports: [MatDialogModule],})export class AppModule { }

Шаг 4: Добавление темы

Добавьте эту строку в файл styles.css

@import "~@angular/material/prebuilt-themes/indigo-pink.css";

Создание перехватчика Angular

Создайте папку для перехватчика с именем приложения. После этого создайте новый файл httpconfig. interceptor. ts в папке интерцептора.

Подключите следующие зависимости в файле httpconfig.interceptor.ts

import { Injectable } from '@angular/core';import { ErrorDialogService } from '../error-dialog/errordialog.service';import { HttpInterceptor, HttpRequest, HttpResponse, HttpHandler, HttpEvent, HttpErrorResponse} from '@angular/common/http';import { Observable, throwError } from 'rxjs';import { map, catchError } from 'rxjs/operators';

В Angular 6 и 7 rxjs map изменяется на путь rxjs/operators. Будьте внимательны во время процесса импортирования.

Создаем класс HttpConfigInterceptor ** и реализуем интерфейс HttpInterceptor**

export class HttpConfigInterceptor implements HttpInterceptor

@Injectable() export class HttpConfigInterceptor implements HttpInterceptor { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {}

В данном примере мы устанавливаем токен Content-Type и Accept type в запросе API.

const token: string = localStorage.getItem('token');
request = request.clone({ headers: request.headers.set('Authorization', 'Bearer ' + token) });
request = request.clone({ headers: request.headers.set('Content-Type', 'application/json') });
request = request.clone({ headers: request.headers.set('Accept', 'application/json') });

Ниже приведен весь код:

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;            }));    }

Из кода, приведенного выше, мы можем установить Content-Type, Accept type и токен в API. Он обрабатывает только API-запрос.

map((event: HttpEvent<any>) => {                if(event instanceof HttpResponse) {                    console.log('event--->>>', event);                    // this.errorDialogService.openDialog(event);                }                return event;            }),

Приведенный выше код будет обрабатывать ответ API. Мы можем обрабатывать каждый отклик API.

Для обработки ответа об ошибке необходимо импортировать модуль rxjs

import { map, catchError } from 'rxjs/operators';

Программный код, приведенный ниже, будет обрабатывать ответ об ошибке:

catchError((error: HttpErrorResponse) => {                let data = {};                data = {                    reason: error && error.error.reason? error.error.reason: '',                    status: error.status                };                this.errorDialogService.openDialog(data);                return throwError(error);            })

Здесь я добавил errorDialogService для обработки ошибок и выведения сообщения об ошибке, предназначенного для посетителей. Но сначала необходимо импортировать httpconfig. interceptor. ts ** в модуль AppModule**.

import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';import { HttpConfigInterceptor} from './interceptor/httpconfig.interceptor';

Добавляем класс в провайдеры. Для обработки множественных перехватов устанавливаем multi: true

providers: [{ provide: HTTP_INTERCEPTORS, useClass: HttpConfigInterceptor, multi: true }]

Создание отдельной службы для обработки ошибок

Чтобы обрабатывать ответы об ошибке, создаем новый файл errordialof.sercive.ts с использованием приведенного ниже кода:

import { Injectable } from '@angular/core';import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';import { ErrorDialogComponent } from './errordialog.component';@Injectable()export class ErrorDialogService {    constructor(public dialog: MatDialog) { }    openDialog(data): void {        const dialogRef = this.dialog.open(ErrorDialogComponent, {            width: '300px',            data: data        });        dialogRef.afterClosed().subscribe(result => {            console.log('The dialog was closed');            let animal;            animal = result;        });    }}

Добавляем компонент errordialog.component для выведения диалогового окна о возникновении ошибки.

import { Component, Inject } from '@angular/core';import { MAT_DIALOG_DATA } from '@angular/material';@Component({  selector: 'app-root',  templateUrl: './errordialog.component.html'})anexport class ErrorDialogComponent {  title = 'Angular-Interceptor';  constructor(@Inject(MAT_DIALOG_DATA) public data: string) {}}
<div>    <div>        <p>            Reason: {{data.reason}}        </p>        <p>            Status: {{data.status}}        </p>    </div></div>

Импортируем файл errordialog.service и компонент диалога ошибок в модуль приложения.

Создание примера сервисного файла для HTTP-запроса

У меня есть пример файла службы для вызова API.

LogIn API Customer detail API

I have created the service name called login. service. ts

import { Injectable } from '@angular/core';import { HttpClient } from '@angular/common/http';// import 'rxjs/operator/map';@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');    }}

Добавляем возможность для вызова двух API.

Запуск службы HTTP-клиента в компоненте приложения

Я использовал две возможности function app.componet.ts: для логина API и вызова возможности нажатия кнопки мышки.

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);    });  }}
<!--The content below is only a placeholder and can be replaced.--><div style="text-align:center">  <h1>    Welcome to {{ title }}!  </h1>  <img width="300" alt="Angular Logo" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTAgMjUwIj4KICAgIDxwYXRoIGZpbGw9IiNERDAwMzEiIGQ9Ik0xMjUgMzBMMzEuOSA2My4ybDE0LjIgMTIzLjFMMTI1IDIzMGw3OC45LTQzLjcgMTQuMi0xMjMuMXoiIC8+CiAgICA8cGF0aCBmaWxsPSIjQzMwMDJGIiBkPSJNMTI1IDMwdjIyLjItLjFWMjMwbDc4LjktNDMuNyAxNC4yLTEyMy4xTDEyNSAzMHoiIC8+CiAgICA8cGF0aCAgZmlsbD0iI0ZGRkZGRiIgZD0iTTEyNSA1Mi4xTDY2LjggMTgyLjZoMjEuN2wxMS43LTI5LjJoNDkuNGwxMS43IDI5LjJIMTgzTDEyNSA1Mi4xem0xNyA4My4zaC0zNGwxNy00MC45IDE3IDQwLjl6IiAvPgogIDwvc3ZnPg=="></div><h2>Here are some links to help you start: </h2><ul>  <li>    <h2><a target="_blank" rel="noopener" href="https://angular.io/tutorial">Tour of Heroes</a></h2>  </li>  <li>    <h2><a target="_blank" rel="noopener" href="https://github.com/angular/angular-cli/wiki">CLI Documentation</a></h2>  </li>  <li>    <h2><a target="_blank" rel="noopener" href="https://blog.angular.io/">Angular blog</a></h2>  </li>  <li>    <h2><p(click)="getCustomerDetails()">Get customer details</p></h2>  </li></ul><router-outlet></router-outlet>

Вот так выглядит диалоговое окно обработчика ошибок:

Angular 6 & 7 HTTP Client Interceptor с обработкой ошибок

Пример кода

Я разместил полный код примера на github. Вы можете запустить npm и сервер ng для тестирования кода. Не забудьте настроить адрес API URL серверной части в файле входа в систему.

Заключение

Мы рассмотрели, как обрабатывать http-запрос и ответ на него с использованием перехватчиков в Angular 6 и 7 interceptor.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *