Angular version 4.3.1 introduced one important new feature: the new HTTP client. Not only did it bring optimizations in how we can execute requests to backend APIs, but it made intercepting HTTP requests extremely easy.

Contents are based on Angular version >= 4.3.1

In the following Egghead.io video lesson I implement an HTTP interceptor which intercepts the request, adding some headers, the response as well as potential HTTP errors.

Table of contents

The new HTTP client

Installing and Registering

The new HTTP client resides in the @angular/common package under the @angular/common/http. You need to register the HttpClientModule and register the interceptor on the HTTP_INTERCEPTORS.

// app.module.ts
...
import { HttpClientModule, HTTP_INTERCEPTORS } from [email protected]/common/http';

// your interceptor file
import { MyHttpLogInterceptor } from './http.interceptor';

@NgModule({
  imports: [ ..., HttpClientModule ],
  providers: [
    { provide: HTTP_INTERCEPTORS, useClass: MyHttpLogInterceptor, multi: true }  
  ],
  ...
})
export class AppModule {}

An HTTP interceptor is just an Angular service implementing a specific interface, the HttpInterceptor.

// http.interceptor.ts
import { Injectable } from [email protected]/core';
import {
  HttpInterceptor,
  HttpRequest,
  HttpHandler,
  HttpEvent
} from [email protected]/common/http';

import { Observable } from 'rxjs/Observable';

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

Intercepting HTTP requests

To intercept the request before it is sent to the server, we need to clone the request object and accordingly add the information we want.

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

    // add a custom header
    const customReq = request.clone({
      headers: request.headers.set('app-language', 'it')
    });

    // pass on the modified request object
    return next.handle(customReq);
  }
}

Intercepting HTTP responses

To intercept the response coming back from the server, we can simply hook on the do(..) operator as the new HTTP module heavily relies on the Observable API.

...
import {
  HttpInterceptor,
  HttpRequest,
  HttpResponse,
  HttpErrorResponse,
  HttpHandler,
  HttpEvent
} from [email protected]/common/http';

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/do';

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

    return next
      .handle(customReq)
      .do((ev: HttpEvent<any>) => {
        if (ev instanceof HttpResponse) {
          console.log('processing response', ev);
        }
      });
  }
}

Intercepting HTTP request errors

Similarly, for catching response errors, the catch Observable operator can be used.

import {
  HttpInterceptor,
  HttpRequest,
  HttpResponse,
  HttpErrorResponse,
  HttpHandler,
  HttpEvent
} from [email protected]/common/http';

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';

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

    return next
      .handle(customReq)
      .do((ev: HttpEvent<any>) => {
        ...
      })
      .catch(response => {
        if (response instanceof HttpErrorResponse) {
          console.log('Processing http error', response);
        }

        return Observable.throw(response);
      });
  }
}

Runnable Plunker

That’s it. Check out the Egghead video lesson at the beginning of this article or simply start playing straight away with this runnable Plunker. Just open it in another window and inspect the console.log statements on the your browser’s devtools.


If you enjoyed this post you might want to follow me on Twitter for more news around JavaScript and Angular or watch my Egghead.io video lessons. :smiley: