Angular 6 Http Interceptor - with Node.js RestAPIs

Tags: angular, interceptor, node
Published: 2021-03-17 15:10:58

https://grokonez.com/frontend/angular/angular-6/angular-6-http-interceptor-with-node-js-restapis

Angular provides HTTP Interception to inspect and transform HTTP requests from your application to the server. In the tutorial, we show how to build an Angular 6 Http Log Interceptor with Node.js RestAPIs.

Related posts:
- <a href="https://grokonez.com/frontend/angular/angular-6/error-handler-angular-6-httpclient-catcherror-retry-with-node-js-express-example">Error Handler Angular 6 HttpClient – catchError + retry – with Node.js/Express example</a>

<!--more-->
<h2>Technologies</h2>
<ul>
<li>Angular 6</li>
<li>RxJS 6</li>
<li>Bootstrap 4</li>
<li>Visual Studio Code – version 1.24.0</li>
<li>Nodejs – v8.11.3</li>
</ul>
<h2>Angular HTTP Interception</h2>
<code>@angular/common/http</code> has a major feature <strong>HTTP Interception</strong> that helps inspect and transform HTTP requests.

Example Log Interceptor:

<pre><code class="language-javascript">
import { HTTP_INTERCEPTORS } from '@angular/common/http';

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

import { finalize, tap } from 'rxjs/operators';
import { LogService } from './log.service';

@Injectable()
export class LoggingInterceptor implements HttpInterceptor {
  constructor(private log: LogService) {}

  intercept(req: HttpRequest<any>, next: HttpHandler) {
    const started = Date.now();
    let ok: string; 

    // Log - start request
    this.log.add("Start request -> " + `${req.method} ${req.urlWithParams}`);

    return next.handle(req)
      .pipe(
        tap(
          // Success Path
          event => ok = event instanceof HttpResponse ? 'succeeded' : '',
          // Fail Path
          error => ok = 'failed'
        ),
        // Log when response observable either completes or errors
        finalize(() => {
          const elapsed = Date.now() - started;
          const log = `${req.method} ${req.urlWithParams}
             ,  ${ok} in ${elapsed} ms.`;

          // Log - end response
          this.log.add("End request: " + log);
        })
      );
  }
}

export const httpInterceptorProviders = [
    { provide: HTTP_INTERCEPTORS, useClass: LoggingInterceptor, multi: true }
];</code></pre>

The <code>intercept</code> method transforms a request into an <code>Observable</code>.
<code>interceptors</code> inspect the request on the way in and forward the request to the <code>handle()</code> method of the <code>next</code> object.
<code>handle()</code> method transforms an HTTP request into an <code>Observable</code> of <code>HttpEvents</code> which include the server's response.

What is <code>next</code> object?
-> The <code>next</code> object represents the next <code>interceptor</code> in the chain of interceptors. The final <code>next</code> in the chain is the Angular <code>HttpClient</code> handler.

How to provide the interceptor?
-> Firstly, importing <code>HTTP_INTERCEPTORS</code>, injection token from <code>@angular/common/http</code>, 

<pre><code class="language-javascript">
import { HTTP_INTERCEPTORS } from '@angular/common/http';

...

export const httpInterceptorProviders = [
    { provide: HTTP_INTERCEPTORS, useClass: LoggingInterceptor, multi: true }
];</code></pre>

-> Then add it to the <code>AppModule</code> providers array:

<pre><code class="language-javascript">
@NgModule({
  declarations: [
    ...
  ],
  imports: [
    ...
  ],
  providers: [
    httpInterceptorProviders
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }
</code></pre>

Now you define a simple Angular Http Get request as below:

<pre><code class="language-javascript">
export class CustomerService {
  private customersUrl = 'http://localhost:8080/api/customers';  // URL to web api
  private handleError: HandleError;

  constructor( 
    private http: HttpClient,  
    httpErrorHandler: HttpErrorHandler,
    private logService: LogService
  ) { 
    this.handleError = httpErrorHandler.createHandleError('CustomerService');
  }

  getCustomers (): Observable<Customer[]> {
    const message = "Info -> Function:  getCustomers. Url: " + this.customersUrl;
    this.logService.add(message);

    return this.http.get<Customer[]>(this.customersUrl)
    .pipe(
      retry(3),
      catchError(this.handleError('getCustomers', []))
    );
  }
</code></pre>



https://grokonez.com/frontend/angular/angular-6/angular-6-http-interceptor-with-node-js-restapis