Меню ×
Angular Interceptors - рабочий пример

Angular Interceptors - рабочий пример

Главной особенностью @angular/common/http является interceptors, возможность объявлять перехватчики, которые находятся между вашим приложением и бэкэндом. Когда ваше приложение делает запрос, перехватчики преобразуют его перед отправкой на сервер (Удобно добавлять заголовки к запросом). Применяется для всего: от аутентификации до логирования.

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

	
ng new interceptors
cd interceptors
ng g service api
	

Создадим сервис api.service.ts, который будет получать данные с jsonplaceholder.typicode.com

	
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';

export interface Posts {
  userId: number;
  id: number;
  title: string;
  body: string;
}

@Injectable()
export class ApiService {

  private postsURL = 'https://jsonplaceholder.typicode.com/posts';

  constructor(private http: HttpClient) { }

  getData(): Observable {

    return this.http
      .get(this.postsURL);
  }

}
	

В главный модуль app.module.ts добавляем

	
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http'; // <- добавлено

...
  imports: [
    BrowserModule,
    HttpClientModule // <- добавлено
  ],
...
	

HTML код app компонента

	
<div style="text-align:center">
  <h1>
    Welcome to {{title}}!
  </h1>
  <img width="300" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTAgMjUwIj4KICAgIDxwYXRoIGZpbGw9IiNERDAwMzEiIGQ9Ik0xMjUgMzBMMzEuOSA2My4ybDE0LjIgMTIzLjFMMTI1IDIzMGw3OC45LTQzLjcgMTQuMi0xMjMuMXoiIC8+CiAgICA8cGF0aCBmaWxsPSIjQzMwMDJGIiBkPSJNMTI1IDMwdjIyLjItLjFWMjMwbDc4LjktNDMuNyAxNC4yLTEyMy4xTDEyNSAzMHoiIC8+CiAgICA8cGF0aCAgZmlsbD0iI0ZGRkZGRiIgZD0iTTEyNSA1Mi4xTDY2LjggMTgyLjZoMjEuN2wxMS43LTI5LjJoNDkuNGwxMS43IDI5LjJIMTgzTDEyNSA1Mi4xem0xNyA4My4zaC0zNGwxNy00MC45IDE3IDQwLjl6IiAvPgogIDwvc3ZnPg==">
</div>
<div class="container">
  <div class="row">
      <table class="table">
          <thead class="thead-inverse">
            <tr>
                <th class="text-center">ID</th>
                <th class="text-center">Title</th>
                <th class="text-center">Body</th>
            </tr>
          </thead>
          <tbody>
            <tr *ngFor="let post of posts">
                <td>{{post.id}}</td>
                <td class="text-center">{{post.title}}</td>
                <td>{{post.body}}</td>
            </tr>
          </tbody>
      </table>
  </div>
</div>
	

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

Чтобы реализовать перехватчик, нужно создать класс, реализующий интерфейс HttpInterceptor, который имеет один метод intercept(). Он принимает два параметра (req, next) и возварщает Observable. По сути первый параметр входящий запрос, второй - исходящий. Поэтому нам необходимо вернуть запрос, делается через метод handle. Далее следует зарегистрировать класс перехватчика в приложении.

	
ng g class api.interceptor
	

Для начала создадим простой перехватчик, который ничего не делает, просто принимает и отправляет запрос, не изменяя его:

	
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest } from '@angular/common/http';

@Injectable()
export class ParamInterceptor implements HttpInterceptor {
    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        return next.handle(req);
    }
}
	

Теперь нужно зарегистрировать перехватчик. Сделаем это в app.module.ts.

	
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http'; // <- добавлено

import { AppComponent } from './app.component';
import { ApiService } from './api.service';
import { AuthInterceptor, ParamInterceptor } from './api.interceptor';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    HttpClientModule // <- добавлено
  ],
  providers: [
    ApiService, {
    provide: HTTP_INTERCEPTORS,
    useClass: ParamInterceptor,
    multi: true
  }],
  bootstrap: [AppComponent]
})
export class AppModule { }
	

Теперь все запросы в приложении обрабатываются перехватчиком ParamInterceptor. Добавим логики. Будем добавлять параметр UserId = 7, для запросов к серверу jsonplaceholder.typicode.com.

	
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest } from '@angular/common/http';

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

    if (req.url.includes('jsonplaceholder.typicode.com')) {
        const paramReq = req.clone({
            params: req.params.set(
                'userId',
                '7'
            )
        });
        return next.handle(paramReq);
    } else {
        return next.handle(req);
    }

    }
}
	

Функция clone используется, потому что объект req является immutable (Неизменяемым).


Похожие материалы

Тестирование компонентов в Angular формально является задачей тестирования двух сущностей: Html шаблона и Typescript класса. И адекватное тестирование компонента заключается проверке корректной работы шаблона и класса.

Рассмотрим события в Angular. Event Binding. Передача и использование данных с помощью event Binding

ControlValueAccessor - связующее звено между Angular forms API и нативным DOM элементом. Чтобы Angular знал об новом field control необходимо зарегистрировать NG_VALUE_ACCESSOR провайдер.

наверх