Angular 14 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 14 Http Log Interceptor with Node.js RestAPIs.

Related posts:
Error Handler Angular 14 HttpClient – catchError + retry – with Node.js/Express example

Technologies

  • Angular 14
  • RxJS 6
  • Bootstrap 4
  • Visual Studio Code – version 1.24.0
  • Nodejs – v8.11.3

Angular HTTP Interception

@angular/common/http has a major feature HTTP Interception that helps inspect and transform HTTP requests.

Example Log Interceptor:

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, 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 }
];

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

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

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

import { HTTP_INTERCEPTORS } from '@angular/common/http';

...

export const httpInterceptorProviders = [
    { provide: HTTP_INTERCEPTORS, useClass: LoggingInterceptor, multi: true }
];

-> Then add it to the AppModule providers array:

@NgModule({
  declarations: [
    ...
  ],
  imports: [
    ...
  ],
  providers: [
    httpInterceptorProviders
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

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

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 {
    const message = "Info -> Function:  getCustomers. Url: " + this.customersUrl;
    this.logService.add(message);

    return this.http.get(this.customersUrl)
    .pipe(
      retry(3),
      catchError(this.handleError('getCustomers', []))
    );
  }

-> Logs with successful response:

angular-6-httpclient-log-interceptor-example-with-nodejs-backend + log results when successfully

-> Logs when Server die -> failed response:

angular-6-httpclient-log-interceptor-example-with-nodejs-backend + log results when fail

Practice

We create 2 projects:

– Angular project:

angular-6-httpclient-log-interceptor-example-with-nodejs-backend + project structure

– Node.js project:

angular-6-httpclient-log-interceptor-example-with-nodejs-backend + nodejs structure

For both projects {Angular, Node.js}, we re-use sourcecodes of the tutorials ->

Error Handler Angular 14 HttpClient – catchError + retry – with Node.js/Express example

What do we build more in the tutorial?
-> With Angular project, to do list:

  • Create Log Service
  • Create Log Component
  • Implement Log Interceptor
  • Integrate LogService with Customer Service

-> With Node.js RestAPIs, we re-use all the sourcecode in Error Handler Angular 14 HttpClient post.

Create Log Service

/src/app/log.service.ts ->

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class LogService {
  logs: string[] = [];

  add(log: string) {
    this.logs.push(log);
  }

  removeAll() {
    this.logs = [];
  }
}

Create Log Component

src/app/log/log.component.ts ->

import { Component, OnInit } from '@angular/core';
import { LogService } from '../log.service';

@Component({
  selector: 'app-log',
  templateUrl: './log.component.html'
})
export class LogComponent{
  constructor(public logService: LogService) {}
}

src/app/log/log.component.html ->

<div *ngIf="logService.logs.length">
  <h3>Logs</h3>
  <button type="button" class="btn btn-dark" (click)="logService.removeAll()">clear</button>
  <br>
  <ol>
    <li *ngFor='let log of logService.logs'> {{log}} </li>
  </ol>
</div>

Implement Log Interceptor

src/app/log-interceptor.ts ->

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, 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 }
];

– Add LogInterceptor to providers array of AppModule:

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

import { FormsModule }   from '@angular/forms';
import { HttpClientModule }    from '@angular/common/http';

import { AppRoutingModule }     from './app-routing/app-routing.module';

import { AppComponent } from './app.component';
import { CustomerComponent } from './customer/customer.component';
import { CustomerDetailsComponent } from './customer-details/customer-details.component';
import { AddCustomerComponent } from './add-customer/add-customer.component';

import { HttpErrorHandler } from'./http-error-handler.service';
import { httpInterceptorProviders } from './log-interceptor'
import { LogComponent } from './log/log.component';
import {LogService} from './log.service'

@NgModule({
  declarations: [
    AppComponent,
    CustomerComponent,
    CustomerDetailsComponent,
    AddCustomerComponent,
    LogComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    AppRoutingModule,
    HttpClientModule
  ],
  providers: [
    HttpErrorHandler, 
    LogService,
    httpInterceptorProviders
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

Integrate LogService with Customer Service

src/app/customer.service.ts ->

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs';
import { catchError, retry } from 'rxjs/operators';

import { Customer } from './customer';

import { HttpErrorHandler, HandleError } from './http-error-handler.service';
import { LogService } from './log.service';

const httpOptions = {
  headers: new HttpHeaders({ 'Content-Type': 'application/json' })
};

@Injectable({
  providedIn: 'root'
})
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 {
    const message = "Info -> Function:  getCustomers. Url: " + this.customersUrl;
    this.logService.add(message);

    return this.http.get(this.customersUrl)
    .pipe(
      retry(3),
      catchError(this.handleError('getCustomers', []))
    );
  }

  getCustomer(id: number): Observable {
    const url = `${this.customersUrl}/${id}`;

    const message = "Info -> Function:  getCustomer. Url: " + url;
    this.logService.add(message);

    console.log(message);

    return this.http.get(url)    
      .pipe(
        retry(3),
        catchError(this.handleError('addCustomer', null))
      );
  }

  addCustomer (customer: Customer): Observable {
    const message = "Info -> Function:  addCustomer. Url: " + this.customersUrl;
    this.logService.add(message);

    console.log(message);

    return this.http.post(this.customersUrl, customer, httpOptions)
      .pipe(
        retry(3),
        catchError(this.handleError('addCustomer', customer))
      );
  }

  deleteCustomer (customer: Customer | number): Observable<{}> {
    const id = typeof customer === 'number' ? customer : customer.id;
    const url = `${this.customersUrl}/${id}`;

    const message = "Info -> Function:  deleteCustomer. Url: " + url;
    this.logService.add(message);

    console.log(message);

    return this.http.delete(url, httpOptions)      
      .pipe(
        retry(3),
        catchError(this.handleError('deleteCustomer', null))
      );
  }

  updateCustomer (customer: Customer): Observable {
    const message = "Info -> Function:  updateCustomer. Url: " + this.customersUrl;
    this.logService.add(message);

    console.log(message);

    return this.http.put(this.customersUrl, customer, httpOptions)
      .pipe(
        catchError(this.handleError('updateCustomer', null))
      );
  }
}

SourceCode

Angular-6-Http-Interceptor
Node.js-RestAPIs

105 thoughts on “Angular 14 Http Interceptor – with Node.js RestAPIs”

  1. Whats up very nice blog!! Man .. Excellent .. Amazing ..
    I will bookmark your site and take the feeds also? I am glad to find so
    many helpful information right here within the put up, we
    need work out extra techniques in this regard, thank you for sharing.
    . . . . .

  2. Great site. Lots of useful information here. I am sending it to a few pals ans also sharing in delicious.
    And obviously, thanks for your sweat!

  3. Howdy! This article couldn’t be written any better!
    Going through this article reminds me of my previous roommate!
    He constantly kept preaching about this. I most certainly
    will send this information to him. Fairly certain he will have a good read.
    Many thanks for sharing!

  4. I was suggested this blog by my cousin. I am not sure whether this post
    is written by him as no one else know such detailed about my
    trouble. You’re incredible! Thanks!

  5. Hi my family member! I wish to say that this article is amazing, nice written and come with approximately all vital infos.
    I would like to look more posts like this .

  6. Thank you, I have recently been searching for info about this
    topic for ages and yours is the best I have found out so far.
    However, what about the conclusion? Are you positive concerning
    the source?

  7. Hello there, You’ve done an excellent job. I’ll certainly digg it and personally suggest to my friends.
    I’m confident they’ll be benefited from this website.

  8. When someone writes an paragraph he/she keeps the image of
    a user in his/her mind that how a user can understand
    it. So that’s why this paragraph is perfect.

    Thanks!

  9. With havin so much content do you ever run into any
    issues of plagorism or copyright violation? My site has a lot of exclusive
    content I’ve either created myself or outsourced but it appears a lot of it is popping it up all over the internet without
    my agreement. Do you know any solutions to help stop content from being ripped off?
    I’d really appreciate it.

  10. I have been browsing online more than three hours nowadays, but I by no means found any interesting article like
    yours. It’s lovely price enough for me. In my
    view, if all web owners and bloggers made just right content as you did, the
    internet can be a lot more useful than ever before.

  11. Good web site you have got here.. It’s hard to find quality writing like yours these days.
    I seriously appreciate individuals like you!
    Take care!!

  12. Very nice post. I just stumbled upon your weblog and wished to say that I have really enjoyed
    surfing around your blog posts. In any case I’ll be subscribing to your feed and I hope you write again very soon!

  13. I am not sure where you are getting your info, but great topic.
    I needs to spend some time learning much more or understanding more.
    Thanks for excellent info I was looking for this information for my mission.

  14. When I originally commented I seem to have clicked the
    -Notify me when new comments are added- checkbox and now each time a comment
    is added I get 4 emails with the exact same comment.
    Is there an easy method you can remove me from that service?
    Thanks a lot!

  15. Hey would you mind letting me know which webhost you’re utilizing?
    I’ve loaded your blog in 3 different internet browsers
    and I must say this blog loads a lot quicker then most.
    Can you recommend a good hosting provider at a honest
    price? Kudos, I appreciate it!

  16. Do you mind if I quote a couple of your articles as long as I provide credit and sources
    back to your website? My blog site is in the very same niche as yours and my visitors would truly benefit from a lot of the
    information you present here. Please let me know if this okay with you.

    Thanks a lot!

  17. Hey there would you mind letting me know which web host you’re using?
    I’ve loaded your blog in 3 different internet browsers and I must say this blog loads a lot quicker then most.
    Can you recommend a good internet hosting provider
    at a honest price? Thanks a lot, I appreciate it!

  18. I’ve been browsing online more than 3 hours today, yet I never found any interesting
    article like yours. It is pretty worth enough for me.
    In my opinion, if all site owners and bloggers made good
    content as you did, the web will be a lot more useful than ever
    before.

  19. I’m very happy to discover this page. I wanted
    to thank you for your time just for this wonderful read!!
    I definitely really liked every little bit of it and I have you book marked
    to see new information on your web site.

  20. I’d like to thank you for the efforts you’ve put in penning this blog.
    I really hope to view the same high-grade content by you later on as well.
    In fact, your creative writing abilities has inspired me to get my own blog now 😉

  21. This design is wicked! You certainly know how to keep
    a reader entertained. Between your wit and your videos, I was
    almost moved to start my own blog (well, almost…HaHa!) Great job.

    I really loved what you had to say, and more than that, how you presented it.

    Too cool!

  22. Sie haben ihren eigenen Pool. Unter Corona ist das verboten. Die Baustelle liegt auf Eis.
    Den kompletten Maßnahmenkatalog des Tourismusministeriums scheint noch keiner gesehen aufgeschlossen. Yesim
    Yalcin ist Ärztin in Antalya und macht ein paar Tage mit ihrem Bruder und seiner Frau hier Urlaub.

    Das Hotel bleibe diese Saison am besten zu. Normalerweise wird dann war’s
    das des Fastenmonats mit Familie und Freunden gefeiert.
    Nicht nur Sevki Erdogan hofft, dass viele Einschränkungen Anfang Juni fallen. Bis Mitte Juni warnt die Bundesregierung allerdings alle Deutschen,
    ins Ausland zu reisen. Um deutsche Urlauber trotz Corona
    wieder in die Türkei zu locken, holt die Regierung in Ankara den TÜV ins Boot.

    Nun sind seine Hotelzimmer alle leer, nur schon so einige der luxuriösen Villen sind belegt.
    Ein Hotelzimmer hätte sie allerdings nicht genommen.
    Die dürfen just in diesem Moment allerdings verstauben. Ferienhäuser werden diese
    Saison wohl insgesamt mehr gefragt sein. Schwimmen und Spazieren am Meer ist verboten. Die Türkei will, dass sie das so weit wie den Sommerferien aufhebt.
    Der Küstenort Kas in der Türkei im Oktober 2019 – damals war die Welt noch frei von Corona.
    Bad monadisch der Zimmer begutachtet. Im kleinen Boutique-Hotel fragen umso mehr Merih Ciraks Stammgäste, wann sie diese Saison aufmacht.
    Der Hotelchef kann das in Rätseln sprechen “Es herrscht einige Entscheidungen, die bringt nichts”,
    sagt er. Ihr Vater bleibt dagegen dabei: Urlaub mit Corona mache keinen Spaß und sei gefährlich.
    Sicher ist das aber nicht.

  23. Am kommenden Montag starten in Nordrhein-Westfalen die Sommerferien. Doch nach dem Corona-Ausbruch im Schlachtbetrieb Tönnies gelten im Landkreis Gütersloh erneut strenge Einschränkungen, gefühlt Ausbreitung des Virus einzudämmen. In den Urlaub können die Bewohner trotzdem fahren, sagt Ministerpräsident Laschet
    – nur sind sie schon jetzt nicht mehr in allen Urlaubsregionen willkommen. Und
    ich befürchte sich auch auf die geplanten Urlaubsreisen der Anwohner auswirken. Das solle auch
    kontrolliert werden. Und selbst ohne Ausreisesperre
    könnte die Ferienreise für die Gütersloher schwierig werden. Der Landkreis Gütersloh steht kurz vor den Sommerferien unter einem “Lockdown”.
    Ein direktes Ausreiseverbot gilt für die rund 370.000 in dem Landkreis lebenden Bewohner zwar nicht, wie
    Ministerpräsident Armin Laschet betonte: “Wer Urlaub plant, kann das natürlich machen.” Im nächsten Atemzug
    rief er die Bürger aber dazu auf, “ein andermal aus dem Kreis heraus in andere Kreise zu fahren”.
    Denn schon jetzt stehen mehrere Urlaubsregionen bundesweit den potenziellen Gästen aus der “Lockdown”-Region skeptisch gegenüber.

  24. Die Grenze zwischen Portugal und Spanien ist geschlossen. Auch die Balearen,
    die Kanaren und Galicien gelten sehr knapp Risikogebiet.
    Ihr könnt es entweder online ausfüllen oder euch die kostenlose SpTH-App herunterladen. Risikogebiet:
    Ja, ausgenommen sind die autonomen Gemeinschaften Valencia und Murcia.
    Der Code kann maximal 48 Stunden vor Einreise erstellt werden. Sie haben nicht nur einen Erfahrungsbericht geschrieben, sondern auch einen kleinen Rundgang gefilmt.

    Seit dem 01.07.2020 müssen alle Einreisenden ein elektronisches Formular im Spain Travel Health-Portal ausfüllen. FTItraveller waren vergangenes Jahr für
    euch auf Rhodos unterwegs und haben sich auch einige Hotels angesehen, ansonsten unseren jetzigen Hoteltipp.

    An der Grenze erfolgen zusätzlich umfassende Gesundheitskontrollen. Einreisebestimmungen:
    Einreisen nach Spanien sind möglich. Negativer PCR Test / Quarantäne:
    Reisende aus Risikogebieten (Aktuell zählt auch Deutschland dazu) müssen seit dem 23.11.2020 einen negativen PCR Test, der nicht älter ist als 72 Stunden, vorweisen. Wenn
    ihr mehr über die Insel erfahren wollt, gelangt ihr hier zu unseren Reisetipps,
    den schönsten Sehenswürdigkeiten und natürlich Stränden.

  25. Great beat ! I would like to apprentice while you amend your
    website, how can i subscribe for a blog web site? The account helped
    me a acceptable deal. I had been a little bit acquainted of this your broadcast provided bright clear idea

  26. Unquestionably imagine that that you said.
    Your favorite reason appeared to be on the net the easiest thing to take note of.
    I say to you, I certainly get annoyed while folks think about worries that they plainly
    do not know about. You managed to hit the nail upon the top as neatly as outlined out the entire
    thing with no need side-effects , people
    could take a signal. Will likely be again to get more. Thanks

  27. Very good blog you have here but I was curious about if you
    knew of any user discussion forums that cover the same topics discussed in this article?

    I’d really like to be a part of community where I can get comments from other experienced
    people that share the same interest. If you have any recommendations, please let me know.
    Thank you!

  28. When I originally left a comment I seem to have clicked on the -Notify me when new comments are added- checkbox and now every time
    a comment is added I receive 4 emails with the same comment.
    Is there an easy method you are able to remove me from that service?
    Thanks!

  29. Howdy outstanding blog! Does running a blog such as
    this take a lot of work? I’ve virtually no understanding of programming but I was hoping to start my
    own blog in the near future. Anyhow, should you
    have any ideas or tips for new blog owners please share.
    I know this is off topic but I just had to ask. Many thanks!

  30. I know this if off topic but I’m looking into starting my own weblog and was wondering what all
    is required to get set up? I’m assuming having a blog like yours would cost a pretty penny?

    I’m not very web smart so I’m not 100% certain. Any tips or
    advice would be greatly appreciated. Cheers

  31. Hello There. I discovered your weblog using msn. This is a
    very neatly written article. I’ll be sure to bookmark it and come back to learn more of your useful information. Thanks for the post.
    I’ll certainly comeback.

  32. Please let me know if you’re looking for a writer for your
    blog. You have some really great articles and
    I think I would be a good asset. If you ever want to take some of the load off,
    I’d absolutely love to write some material for your blog
    in exchange for a link back to mine. Please send me an email if interested.
    Thanks!

  33. This is very fascinating, You’re an excessively professional
    blogger. I’ve joined your feed and stay up for searching for extra of your wonderful post.
    Additionally, I’ve shared your web site in my social networks

  34. Having read this I thought it was very enlightening.

    I appreciate you finding the time and effort to put this short article together.
    I once again find myself spending a significant amount of time both reading and commenting.
    But so what, it was still worth it!

  35. It’s actually a cool and helpful piece of information. I am satisfied that
    you simply shared this helpful info with us. Please keep us up to date like this.
    Thank you for sharing.

  36. hello!,I really like your writing very so much!
    percentage we keep up a correspondence extra about your post
    on AOL? I need an expert in this house to solve my problem.
    Maybe that is you! Looking forward to look you.

  37. Hey just wanted to give you a brief heads up and let you know a few of the pictures aren’t loading correctly.
    I’m not sure why but I think its a linking issue.

    I’ve tried it in two different internet browsers and
    both show the same results.

  38. Simply desire to say your article is as amazing.
    The clarity to your post is simply excellent and i can assume you’re an expert on this subject.
    Well with your permission let me to snatch your feed to keep up to date with drawing close post.
    Thanks one million and please continue the enjoyable work.

  39. Hi! I’ve been following your weblog for
    a long time now and finally got the bravery to go ahead and give you a shout out from Dallas Tx!
    Just wanted to tell you keep up the good work!

  40. This is the right website for everyone who would like to understand this topic.

    You understand a whole lot its almost tough to argue with you (not that I
    personally would want to…HaHa). You certainly put a fresh spin on a subject that has been written about for
    decades. Great stuff, just great!

  41. Have you ever thought about adding a little bit more than just your articles?
    I mean, what you say is valuable and everything. Nevertheless just imagine
    if you added some great visuals or video clips to give your posts more, “pop”!

    Your content is excellent but with pics and video clips, this
    site could certainly be one of the best in its field.
    Good blog!

  42. I’m really enjoying the theme/design of your web site.
    Do you ever run into any web browser compatibility issues?

    A handful of my blog visitors have complained about my site
    not operating correctly in Explorer but looks great in Safari.

    Do you have any tips to help fix this issue?

  43. It’s a pity you don’t have a donate button!
    I’d definitely donate to this outstanding blog! I suppose for now
    i’ll settle for bookmarking and adding your RSS feed to my Google account.
    I look forward to fresh updates and will share this site with my Facebook group.
    Talk soon!

  44. I really like your blog.. very nice colors & theme.
    Did you create this website yourself or did you hire someone
    to do it for you? Plz reply as I’m looking to construct my own blog
    and would like to find out where u got this from. thank you

Leave a Reply

Your email address will not be published.