What are Interceptors?
Interceptors check each and every incoming and outgoing request to the server and are also able to manipulate them before actually sending to the server.
Imagine the use case where we need to send the user authentication token each and every time with the HTTP request we are sending to the server. So, instead of writing/fetching the token in every request, we can simply create the interceptors, which will inspect our HTTP request, manipulate it (add auth token), and then actually pass it to the server.
In another use case, we need to pass the headers with each and every HTTP request, so instead of passing it to every request, we can create interceptors which inspects our request, manipulates it with headers, and passes it to the server.
In the same way, interceptors can also be used when we receive the data from the server. So, before passing the actual data to the component, an interceptor can also be used to manipulate the data.
Without interceptors, we would have to implement all the tasks explicitly for each HTTP Client method.
Intercepting Request
Creating an interceptor is very simple; just declare a class that implements the intercept () method of the HttpInterceptor Interface, which can be imported from @angular/common/http. Below is the code snippet of newly created Interceptor.
- import {
- HttpInterceptor,
- HttpRequest,
- HttpHandler,
- HttpEvent
- } from "@angular/common/http";
- import {
- Observable
- } from "rxjs";
- export class interceptorclass implements HttpInterceptor {
- intercept(req: HttpRequest < any > , next: HttpHandler): Observable < HttpEvent < any >> {
- console.log(httpreq);
- return next.handle(httpreq);
- }
- }
Intercept method will take 2 arguments.
HttpRequest
It is the actual request which we are making through over services or component. These requests are always immutable so it can not be edited directly.
- req.url = req.url.replace('http://', 'https://'); this will not work directly because it is readonly.
To make it work, we first need to clone the request and then we can make changes on cloned request only. Below is the code snippet for cloned URL by interceptors.
- intercept(req: HttpRequest < any > , next: HttpHandler): Observable < HttpEvent < any >> {
- const httpreq = req.clone({
- url: req.url.replace('http://', 'https://');
- });
- console.log(httpreq);
- return next.handle(httpreq);
- }
HttpHandler
In most of the cases, Interceptors will call.
- next.handle(httprequest-object);
Which will call the next handler in the chain or eventually the back-end handler. An interceptor skips calling next.handle() and can also return its own Observable.
By only just defining interceptors will do nothing. In order to make an interceptor work, we must provide the interceptors in the app.module.ts file as shown below.
Providing Interceptors
- 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 {
- intercepterclass
- } from './intercepterclass';
- @NgModule({
- declarations: [
- AppComponent
- ],
- imports: [
- BrowserModule,
- HttpClientModule
- ],
- providers: [{
- provide: HTTP_INTERCEPTORS,
- useClass: interceptorclass,
- multi: true
- }],
- bootstrap: [AppComponent]
- })
- export class AppModule {}
Note
By providing Multi: true, means we can allow multiple interceptors.
So now, to check out if the interceptor is working or not, I will make an HTTP Request through my app.component.ts, which, in turn, calls to our task.service.ts which will call the interceptorclass. Below is the code snippet of app.component.ts and task.service.ts files respectively.
- import {
- TaskService
- } from './task.service';
- import {
- Component,
- OnInit
- } from '@angular/core';
- import {
- Task
- } from './task';
- @Component({
- selector: 'app-root',
- templateUrl: './app.component.html',
- styleUrls: ['./app.component.css']
- })
- export class AppComponent implements OnInit {
- title = 'httpclientDemo';
- ngOnInit() {
- this._taskdata.getAllTask().subscribe(
- (data) => {
- console.log("selected" + data);
- });
- }
- }
Task.service.ts
- import {
- Task
- } from './task';
- import {
- Injectable
- } from '@angular/core';
- import {
- HttpClient
- } from '@angular/common/http';
- @Injectable({
- providedIn: 'root'
- })
- export class TaskService {
- url: string = 'http://rkdemotask.herokuapp.com/tasks/';
- constructor(public _http: HttpClient) {}
- getAllTask() {
- return this._http.get < Task > (this.url);
- }
- }
So, as you can see from the above code snippet, we are making a call to http:// , but this call will go through our interceptors which will eventually replace http:// with https://.
In the same way, we can use Interceptors to add headers. The code of the interceptors is shown below.
- import {
- HttpInterceptor,
- HttpRequest,
- HttpHandler,
- HttpEvent
- } from "@angular/common/http";
- import {
- Observable
- } from "rxjs";
- export class intercepterclass implements HttpInterceptor {
- intercept(req: HttpRequest < any > , next: HttpHandler): Observable < HttpEvent < any >> {
- const httpreq = req.clone({
- url: req.url.replace('http://', 'https://'),
- headers: req.headers.set('Content-Type', 'application/json')
- });
- console.log(httpreq);
- return next.handle(httpreq);
- }
- }
I hope this will be helpful to you in understanding Interceptors.
Thank you for reading.