HTTP Interceptors In Angular
In this article, we will learn about the HTTP Interceptors in Angular. Along with the new HTTPClientModule, the Angular HTTP Interceptor is introduced. By intercepting the HTTP Request before it is sent to the back end, the Interceptor allows us to change it. The Interceptor can be used to add custom headers to incoming requests, log incoming responses, and so on. Using a few examples, this article demonstrates how to use an Angular HTTP interceptor.
What is an angular HTTP Interceptor?
Our application and the backend are separated by the Angular HTTP interceptors. The interceptor intercepts a request made by the application before it is transmitted to the backend. We will gain access to request headers and bodies by intercepting requests. This allows us to modify the request before it is sent to the server.
The Interceptors can alter the response from the back end before providing it to our application.
The ability to add the Authorization Header to every request is one of the key advantages of the HTTP Interceptors. We could do it manually, but it would be time-consuming and error-prone. Another advantage is that the request's faults are caught and logged.
How to Create HTTP Interceptor
Create an injectable service that implements the HttpInterceptor interface to implement the Interceptor.
@Injectable() export class AppHttpInterceptor implements HttpInterceptor {
The method Intercept must be implemented by this class.
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { //do whatever you want with the HttpRequest return next.handle(req); }
The HTTP_INTERCEPTORS token is then used to give this class in the Root Module:
providers: [ { provide: HTTP_INTERCEPTORS, useClass: AppHttpInterceptor, multi: true } ],
HttpInterceptor Interface
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>
HttpRequest
HttpHandler
HTTP Interceptor Example
Create the Interceptor
import {Injectable} from "@angular/core"; import {HttpEvent, HttpHandler, HttpInterceptor,HttpRequest} from "@angular/common/http"; import {Observable} from "rxjs/Observable"; @Injectable() export class AppHttpInterceptor implements HttpInterceptor { constructor() { } intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { console.log(req); return next.handle(req); } }
import {Injectable} from "@angular/core"; import {HttpEvent, HttpHandler, HttpInterceptor,HttpRequest} from "@angular/common/http"; import {Observable} from "rxjs/Observable";
export class AppHttpInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { //Do whatever you want to do with the Request console.log(req); return next.handle(req); }
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { HttpClientModule,HTTP_INTERCEPTORS} from '@angular/common/http'; import { FormsModule } from '@angular/forms'; import { AppComponent } from './app.component'; import { GitHubService } from './github.service'; import {AppHttpInterceptor} from './AppHttpInterceptor'; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, HttpClientModule, FormsModule ], providers: [GitHubService, { provide: HTTP_INTERCEPTORS, useClass: AppHttpInterceptor, multi: true } ], bootstrap: [AppComponent] }) export class AppModule { }
We'll start by importing HttpClientModule and HTTP_INTERCEPTORS from @angular/common/http.
import { HttpClientModule,HTTP_INTERCEPTORS} from '@angular/common/http';
Then, for the HTTP_INTERCEPTORS, register AppHttpInterceptor as the Provider.
providers: [GitHubService, { provide: HTTP_INTERCEPTORS, useClass: AppHttpInterceptor, multi: true }
Setting the new headers
Adding the Content-Type
req = req.clone({ headers: req.headers.set('Content-Type', 'application/json') });
req = req.clone({ headers: req.headers.append('Content-Type', 'application/json') });
You can also use the setHeaders shortcut, which is demonstrated below.
req = req.clone( {setHeaders: {‘Content-Type’: ‘application/json’}} );
You might wish to use headers to see if the header already exists. header.has() is a method that checks if something exists.
if (!req.headers.has('Content-Type')) { req = req.clone({ headers: req.headers.set('Content-Type', 'application/json') }); }
Check the header's current value.
req.headers.get('Accept')
Also, a header should be removed.
req = req.clone({ headers: req.headers.delete('Content-Type','application/json') });
Adding the Authorisation token
const token: string =authService.Token; //Get token from some service if (token) { req = req.clone({ headers: req.headers.set('Authorization', 'Bearer ' + token) }); }
Intercepting the Response
Logging
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { req = req.clone({ headers: req.headers.append('Content-Type', 'application/json')}); const started = Date.now(); return next.handle(req) .do(event => { console.log(event); const elapsed = Date.now() - started; console.log(`Request for ${req.urlWithParams} took ${elapsed} ms.`); if (event instanceof HttpResponse) { console.log(`Response Received`); }; }); }
Modify Response
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { return next.handle(req) .map(resp => { const myBody = [{ 'id': '1', 'name': 'TekarticlesHub', 'html_url': 'www.tekarticleshub.com', 'description': 'description' }]; // on Response if (resp instanceof HttpResponse) { console.log(resp); console.log(resp.body); resp = resp.clone<any>({ body: myBody}); return resp; } }); }
Catching the Error
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { const token: string = 'invald token'; req = req.clone({ headers: req.headers.set('Authorization', 'Bearer ' + token) }); return next.handle(req) .map(resp => { // on Response if (resp instanceof HttpResponse) { // Do whatever you want with the response. return resp; } }).catch(err => { // onError console.log(err); if (err instanceof HttpErrorResponse) { console.log(err.status); console.log(err.statusText); if (err.status === 401) { // redirect the user to login page // 401 unauthorised user } } return Observable.of(err); }); }
Cancel the current Request
import { EMPTY } from 'rxjs'; intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { if (NotLoggedIn) { return EMPTY; } return next.handle(request); }
Change the Requested URL
const baseURL="https://www.tekarticlesHub.com/"; intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { const newReq = req.clone({ url: baseURL + req.url; }); return next.handle(httpsReq); }