Angular 9, Build dynamic HttpClient and Http Interceptor in details


You probably know that Angular introduced a powerful HttpClient and One of its features is Http interceptors, Interceptors are provided in code to set in between your Http request and the backend 
Here I’ll dig deeper into HttpClient and interceptors in particular.


Angular project setup

1-Create new angular project using angular cli (ng new client-app)
2- after project setup create new service (ng generate service client

HttpClient


the HttpClient is declared in @angular/common/http that uses XmlHttpRequest to send your request to backend.

as you know modern browsers support two different APIS for making Http request
 1- XmlHttpRequest
 2 - Fetch API

HttpClient Setup

before you can use HttpClient you need to import HttpClientModule


import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import {HttpClientModulefrom '@angular/common/http';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    HttpClientModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }


after importing HttpClientModule you can inject HttpClient in your client service


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

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

  constructor(private http:HttpClient) { }
}


Implement dynamic request method as your middleware

 private request(methodstringurlstringheaders:HttpHeaderspostBody?: string) {

    let request = new HttpRequest(methodurlpostBody, { headers: headers });

    return this.http.request(request);
  }

let's assume you want to get all your clients, then let's implement an Http request to consume your middleware

public getTotalClients() {

    let headers = new HttpHeaders();
    headers = headers.append('filter''{"allClients":true}');
     
    return this.request("GET","http://localhost:4251/api/clients",headers)
    
  }


now  your HttpClient is ready for requesting backend APIS

Http Interceptor

Http Interceptors are a major feature of HttpClient, you can use Http Interceptors for authentication,logging, manage Http request in a routine or a dynamic way.

To implement interceptors you need to declare a class that implements the intercept() method of HttpInterceptor.

import { Injectable } from '@angular/core';
import {HttpEventHttpInterceptorHttpHandlerHttpRequest}
 from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable()
export class NoopInterceptor implements HttpInterceptor {

  intercept(reqHttpRequest<any>, nextHttpHandler):Observable<HttpEvent<any>> {
      
    return next.handle(req);
  }
}


The intercept method transforms a request into an Observable that eventually returns the HTTP response. 
Most interceptors inspect the request and forward it to the handle() method of the next object,
The next object represents the next interceptor in the chain of interceptors. The final next in the chain is the HttpClient backend handler that sends the request to the server and receives the server's response.

Provide the interceptor


interceptors are provided in the same injector of your HttpClient 

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HttpClientModuleHTTP_INTERCEPTORS } from '@angular/common/http';


import { ClientInterceptor } from './ClientInterceptor';

export const HttpIntertceptorsProvider =
{
  provide: HTTP_INTERCEPTORS,
  useClass: ClientInterceptor,
  multi: true
}

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    HttpClientModule
  ],
  providers: [HttpIntertceptorsProvider],
  bootstrap: [AppComponent]
})
export class AppModule { }

The multi: true option. This required setting tells Angular that HTTP_INTERCEPTORS is a token for 
multiprovider that injects an array of values, rather than a single value.



let's create a simple dynamic Interceptor that uses request header and reproduce new headers. assume you are requesting an authorized API that you want to add Authorization every time you request this API.

import { Injectable } from '@angular/core';
import {HttpEventHttpInterceptorHttpHandlerHttpRequestfrom '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable()
export class ClientInterceptor implements HttpInterceptor {

  intercept(reqHttpRequest<any>, nextHttpHandler):Observable<HttpEvent<any>> {

    //clone request headers
    let reqHeader=req.headers;

    //add new headers
    reqHeader=reqHeader.append('Authorization','my-token');

    const cloneReq = req.clone({
        headers:reqHeader
      });

      //pass the new request to the next interceptor
    return next.handle(cloneReq);
  }
}


Conclusion

Ok, Now we know how implement dynamic Http request, how to use interceptors and calling the next handler.











تعليقات