Intercepting HTTP with Angular: A Comprehensive Guide

Hasan Gürel
2 min readMay 15, 2024

--

HTTP interceptors in Angular are classes that implement the HttpInterceptor interface. They serve a variety of purposes related to HTTP requests and responses, including adding headers, handling errors, modifying request or response data, logging activities, and managing authentication, among other tasks.

The main purpose of interceptors is to filter the requests from the client to the backend and reduce the load on the backend.

Here’s an example of a basic interceptor:

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

@Injectable()
export class ExampleInterceptor implements HttpInterceptor {
intercept(httpRequest: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
// Any alteration to httpRequest can be done here
return next.handle(httpRequest);
}
}

In more complex structures, the situation may be slightly different. For example, consider a scenario where you want to handle the authentication of your HTTP requests and log them before sending them to a server. To accomplish this task, you could provide an AuthInterceptor service and a LoggingInterceptor service. Outgoing requests would flow from the AuthInterceptor to the LoggingInterceptor. Responses from these requests would flow in the opposite direction, from LoggingInterceptor back to AuthInterceptor. The following is a visual representation of the process:

[Include a relevant image or diagram here]

Using Interceptors in Angular

To use an interceptor in your Angular application, you need to add the necessary code to your application’s configuration file (typically app.module.ts):

import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { CustomInterceptor } from './custom.interceptor';

@NgModule({
// ...
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: CustomInterceptor,
multi: true,
},
],
// ...
})
export class AppModule {}

Here’s an example of a basic intercept method that handles JWT token management for HTTP requests:

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (localStorage.getItem("jwtToken") == null || localStorage.getItem("jwtToken") == undefined) {
if (req.url.includes("profile")) {
this.authService.getJwtTokenByRefreshToken();
}
}

if (req.url.endsWith("/api/v1/auth/authenticate")) {
return next.handle(req);
} else {
const localToken = localStorage.getItem("jwtToken");
req = req.clone({ headers: req.headers.set('Authorization', `Bearer ${localToken}`) });
return next.handle(req);
}
}
  • The interceptor ensures that a JWT token is present for most requests and adds it to the request headers.
  • It refreshes the token if necessary when accessing profile-related endpoints.
  • It bypasses adding the token for the authentication endpoint itself to avoid issues with token requirements for login requests.

Result

By using interceptors in your Angular application, you can centralize the handling of HTTP requests and responses, making your code more modular, maintainable, and reusable. Interceptors can help you implement cross-cutting concerns, such as authentication, logging, caching, and error handling, without cluttering your component code.

Interceptors are a powerful feature of Angular’s HTTP client that can significantly enhance the functionality and reliability of your application’s communication with APIs and backend services.

Thank you for reading this comprehensive guide on interceptors in Angular. By understanding and utilizing interceptors effectively, you can streamline your development process and create more robust and secure Angular applications.

--

--