Angular HTTP Interceptors

Blog > Angular

Angular HTTP Interceptors

Many built-in tools in Angular help you scale up huge JavaScript apps. Interceptors are one of the built-in tools for dealing with HTTP requests on a global level.

What may interceptors be used for?

  • Handling HTTP headers
  • Handling errors.

The following is an example of an interceptor:

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

   @Injectable()
   export class CustomInterceptor implements HttpInterceptor {
       intercept(httpRequest: HttpRequest, next: HttpHandler): Observable> {
          return next.handle(httpRequest);
       }
   }

The HttpInterceptor interface from the @angular/common/http package must be implemented to build an Interceptor. The Interceptor executes the intercept() function every time our application uses the HttpClient service to perform an HTTP request.

Angular sends a reference to the httpRequest object when the intercept() function is used. We can inspect and change this request as needed using this request.

After we've constructed our Interceptor, we'll need to register it as a multi-provider since an application can have many interceptors operating at the same time. Important: You must register the provider with the app.module in order for it to apply to all HTTP requests made by the application. Only requests that use the HttpClient service will be intercepted by interceptors.

   import { NgModule } from '@angular/core';
   import { BrowserModule } from '@angular/platform-browser';
   import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
   import { RouterModule, Routes } from '@angular/router';
   import { CustomInterceptor } from './my.interceptor';
   import { AppComponent } from './app.component';

   @NgModule({
     imports: [BrowserModule, HttpClientModule],
     declarations: [AppComponent],
     bootstrap: [AppComponent],
     providers: [
       { provide: HTTP_INTERCEPTORS, useClass: CustomInterceptor , multi: true }
     ]
   })
   export class AppModule { }

Next, we'll create an Interceptor that can change request headers as our first Interceptor implementation.

Http Header Interceptor

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

   @Injectable()
   export class HeaderInterceptor implements HttpInterceptor {
     intercept(request: HttpRequest, next: HttpHandler): Observable> {
       let headers = new HttpHeaders();
       headers = headers.append('Authorization', `Bearer JWT_TOKEN`);
       request = request.clone({
           headers: headers,
       });

    return next.handle(request);
  }
}

The request object's clone method can be used to edit the object and return a new copy. In this example, the JWT TOKEN value is appended as a header to each HTTP request.

 request = request.clone({
           headers: headers,
 });

Let's use the HttpClient service to make an HTTP get request.

   import { Component, OnInit } from '@angular/core';
    import { HttpClient } from '@angular/common/http';
    import { Observable } from 'rxjs';
    import { tap } from 'rxjs/operators';

    @Component({
    selector: 'app',
    template: `{{ data | json }}`
    })
    export class AppComponent implements OnInit {
      data: {};
      constructor(private httpClient: HttpClient) { }

      ngOnInit() {
        this.httpClient.get('/assets/data.json').subscribe(data => this.data = data);
      }
    }

The network request containing our new header Authorization with the corresponding value can be seen in browser's dev tools.

 

Error Handling

Interceptors may also be used to handle HTTP failures. There are a few ways for dealing with HTTP failures. We could use the Interceptors to report problems or provide UI notifications when something goes wrong. However, in this example, we'll provide code to retry unsuccessful API queries.

 

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

    @Injectable()
    export class RetryInterceptor implements HttpInterceptor {
    intercept(httpRequest: HttpRequest, next: HttpHandler): Observable> {
        return next.handle(httpRequest).pipe(retry(2));
      }
    }

We may utilize the RxJS retry() operator within our request handler. Retrying failed Observable streams that have produced errors is possible with the retry operator. Observables are used by Angular's HTTP service, allowing us to re-request our HTTP request. The retry operator accepts an argument specifying the desired number of retries. We'll use a value of two in our example, which equals three tries, the first of which is successful.

We'll choose a value of 2, which will result in three attempts: the first and two further retries. If none of the requests succeed, the Observable returns an error to the HTTP request Observable's subscriber.

   import { Component, OnInit } from '@angular/core';
    import { HttpClient } from '@angular/common/http';
    import { Observable, of } from 'rxjs';
    import { catchError } from 'rxjs/operators';

    @Component({
      selector: 'app',
      template: `{{ data | json }}`
    })
    export class AppComponent implements OnInit {
        data: {};

        constructor(private httpClient: HttpClient) { }

        ngOnInit() {
            this.httpClient.get('https://example.com/404').pipe(
                    catchError(err => of('error'))
                    ).subscribe(data => this.data = data);
        }
    }

When we make a faulty request in our component, we may still capture the error with the catchError operator. Only when our Interceptor's final attempt has failed will this error handler be triggered.

 

HTTP Interceptors are another another useful feature in our Angular toolkit for managing HTTP requests.

Tags