November 22, 2019

Transform Http Requests in Angular using Interceptor

Hello everyone, in this tutorial we will implement Http Interceptor in Angular. Interceptors allow us to tap into Http requests/responses globally in order to perform our required transformations.

Here we will use the Http Interceptor to include our sample token in every request header and also to modify the response. This can be useful when all our endpoints are secured and we need to pass on the authentication information in every request header.

For the demo purpose, JsonPlaceholder, which is a fake online REST API, will work as our back end.

Add Sample Token to Session Storage

  • Add a button to the app.component.html file which we will use to simulate the login by adding a sample token to the session storage
  • On click event of this button, add sample string with key “token” in the browser. In real world apps this token will most probably hold your JWT or normal bearer token
<div style="margin: 5px">
    <button type="button" (click)="AddToken()">Simulate Login</button>
</div>
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'interceptor-app';

AddToken()
{
  sessionStorage.setItem("token","sampleBearerToken");
  console.log("Successfully logged in");
  console.log(sessionStorage.getItem("token"));
}
}

Generate the Token Interceptor Service

  • Create a new service called JwtTokenInterceptor
  • Import HttpInterceptor from ‘@angular/common/http’
  • Import the JwtTokenInceptor service in the app.module.ts file for registration
    In the “providers” section add the container for Http_Interceptors to use our token interceptor.
  • “multi:true” allows the usage of multiple interceptors which can be changed together
  • Implement the class from HttpInterceptor and add the method intercept.
  • The intercept method takes in two parameters, the request object and the next. Next allows to pass on the request for further processing or chains in any other interceptor if it exists.
  • Since, Http requests are immutable we will create a clone of our existing request and make the transformation in it.
  • Here we will get the token from the session storage and add it into the header using the setHeaders attribute
  • Finally, we will return our new cloned request using the next.handle function.

Also Read: Implement Jwt in Angular using Asp.Net Web API

import { Injectable } from '@angular/core';
import { HttpInterceptor } from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})
export class JwtTokenInterceptorService implements HttpInterceptor {

   constructor() { }

  intercept(request, next)
  {
    const token = sessionStorage.getItem("token");
    if(token)
    {
      let newRequest = request.clone({
        setHeaders : {
          Authorization: 'Bearer ' + token
        }
      })

      return next.handle(newRequest);
    }
  }
}
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { JwtTokenInterceptorService } from './jwt-token-interceptor.service';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { DataService } from './data.service';

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

Add Service To Get Data

  • Add a new service named DataService
  • Include the required Http modules and add a function to get data from JsonPlaceholder
  • We will now inject this service in the app.component.ts file and call it upon click event of a new button to get the data.
import { Injectable } from '@angular/core';
import {HttpClient} from '@angular/common/http'

@Injectable({
  providedIn: 'root'
})
export class DataService {

  data: any[];

  constructor(private http: HttpClient) { 

  }

  GetData(){
    this.http.get("https://jsonplaceholder.typicode.com/posts/1")
            .subscribe((response) => {
            console.log("Secure Data Recieved");
            console.log(response);
            });
  }
}
import { Component } from '@angular/core';
import { Data } from '@angular/router';
import { DataService } from './data.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'interceptor-app';

  constructor(private service: DataService){}

AddToken()
{
  sessionStorage.setItem("token","sampleBearerToken");
  console.log("Successfully logged in");
  console.log(sessionStorage.getItem("token"));
}

GetSecureData()
{
  this.service.GetData();
}

}
<div style="margin: 5px">
    <button type="button" (click)="AddToken()">Simulate Login</button>
</div>

<div style="margin: 5px">
    <button type="button" (click)="GetSecureData()">Get Secure Data</button>
</div>

On clicking the GetSecureData button we can see the data logged in the console. On moving to the network tab and in our particular Api call, we can see the header added as well.

Note: JsonPlaceholder API’s are unsecured and do not require any credentials to access data. We are just using them here to demonstrate how all API calls can be modified so as to include authentication headers or for any other transformation as well.

Transform Response using Interceptor

  • We will transform the response in the next.handle() method by using the pipe and map operators and checking the instance of the object
  • Import the map operator in the interceptor service from ‘rxjs/operators’
import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpResponse } from '@angular/common/http';
import { map } from 'rxjs/operators';
@Injectable({
  providedIn: 'root'
})
export class JwtTokenInterceptorService implements HttpInterceptor {

   constructor() { }

  intercept(request, next)
  {
    const token = sessionStorage.getItem("token");
    if(token)
    {
      let newRequest = request.clone({
        setHeaders : {
          Authorization: 'Bearer ' + token
        }
      })

      return next.handle(newRequest)
            .pipe(map((resp) => {
                  if(resp instanceof HttpResponse)
                  {
                    return resp.clone({
                      body : {title:"Transformed Http Response"}
                    })
                  }
            })
            )
    }
  }
}

3 thoughts on “Transform Http Requests in Angular using Interceptor

  1. Your Tutorials are really awesome Rajat Sir, I would like to get personal training from you if possible!
    Kindly let me know your availability

Leave a Reply

Your email address will not be published. Required fields are marked *