Interceptors in Angular: HttpInterceptors

Introduction

Interceptors in Angular is a concept in which we can intercept requests and responses. We can handle HTTP requests and responses. Using interceptors, we can achieve a number of advantages such as filtering request URLs, adding headers in the request, showing messages on error response, writing code at one place instead of adding at multiple places. It acts as middleware. We can intercept outgoing requests by transforming it. It also transform the response by applying various operators on the data stream. 

Implementation

We can implement interceptor we need to do the following steps:
  • We will implement the HttpInterceptor and decorate the class using @injectable
  •  In this class, to implement HttInterceptor we should have a method called intercept(). This method will take two arguments: req and next.
  • req refers to the request object which we are sending of type HttpRequest.
  • next is of type HttpHandler. It has a handle method that returns the observable of type HttpEvent.
Following we will see how the intercept method is written.
return next.handle(req) means we are performing no action on the request.

intercept(req: HttpRequest, next: HttpHandler): Observable<httpEvent<any>> {
    return next.handle(req); // This means we are performing no action on the request
  }

Now we will see how we will set header if the token is available after the login of the user. If the URL contains public then we need to set the authorization token to some "abc" rather than access token. Here AuthService will give us the access token after the user login into the application. Then we will set Authorization to bearer access_token.

  • HttpRequest objects can't be changed. So we have to make a copy of it and then transform them. req.clone() method duplicates the object and modifies using RxJS operators. We will pass the cloned modified object to the return next.handle(duplicate).
  • We will provide the interceptors in the app.module.ts file in the providers array.

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

According to the above syntax, we will have a class AppHttpInterceptor that will implement HttpInterceptor. We can have multiple interceptors as well. 

import { Injectable, Injector } from '@angular/core';
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpErrorResponse, HttpHeaders, HttpResponse } from '@angular/common/http';
import 'rxjs/add/operator/do';
import { Observable } from 'rxjs';
import { AuthService } from '../services/auth/auth.service';

@Injectable()
export class AppHttpInterceptor implements HttpInterceptor {
     constructor(
        private _authService: AuthService,
            ) {}

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        let authReq: HttpRequest<any> = null;
            if (this._authService.getToken() != undefined) {
            var access_token = this._authService.getToken();
            const headers = { 'Authorization': 'bearer' + ' ' + access_token };
            authReq = req.clone({
                setHeaders: headers,
            });
        }
        //send the newly created request
        if (authReq === null) {
            authReq = req;
        }
        if (authReq && authReq.url && authReq.url.indexOf('/public') > -1) {
            authReq = authReq.clone({ headers: authReq.headers.set('Authorization', 'abc') })
        }
        return next.handle(authReq)
            .do(event => {
                 if (event instanceof HttpResponse) {
                   console.dir(event);
                 }
            }
    }

}

Comments