Angular Interceptors: A Quick Guide

Full Stack Developer
Ever had your app ask for something from the server, and it's met with a big, "nope" in the form of an error? Frustrating, right?
I found myself in this very situation while working on the development of the frontend in Angular and came across HTTP error 400. In the realm of HTTP/1.1 standards, this error, known as the "Bad Request" response, surfaces when the server is unable or unwilling to process a request due to malformed client input, invalid parameters, or other issues.
The legacy code was only handling the response; since this request did not return a response, the request failed. So, what would be the best way to handle this? Angular interceptors!
Angular interceptors are more than just handling errors. They can also be used to inject authorization tokens in HTTP requests. This gave me the idea to write my first blog on Hashnode. So here I am, with a quick guide to Angular interceptors.
Introduction
Interceptors in Angular are services that can be used to intercept HTTP requests and responses. They provide a way to modify or handle requests and responses globally before they reach the server or the application.
Create an Interceptor:
// Import necessary modules and classes
import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http';
import { Observable } from 'rxjs';
// Decorate the class as an injectable service
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
// Implement the intercept method required by the HttpInterceptor interface
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
// Hardcoded authentication token for demonstration purposes
const authToken = 'your-auth-token';
// Clone the original request and add the authorization header
const authReq = req.clone({
setHeaders: {
Authorization: `Bearer ${authToken}`
}
});
// Pass the cloned request to the next handler in the chain
return next.handle(authReq).pipe(
// Map the response to itself (optional step)
map((response) => response),
// Catch and handle any errors
catchError(this.handleError)
);
}
// Optional: Define a private method to handle errors
private handleError = (error) => {
// Implement error handling logic here
console.error('Error:', error);
// Optionally, throw the error again or handle it gracefully
throw error;
}
}
Explanation:
AuthInterceptoris a class that implements theHttpInterceptorinterface. This interface allows you to intercept and transform HTTP requests or responses.The
interceptmethod is the core of the interceptor. It takes the originalHttpRequestand aHttpHandler. TheHttpHandleris responsible for passing the request along the chain of interceptors and ultimately to the server.In this interceptor, a token (
authToken) is hardcoded for demonstration purposes. In a real-world scenario, you would retrieve the token dynamically, perhaps from a service or another source.The
req.clone()method is used to create a new request based on the original request (req). This new request includes an additional header (Authorization) with the token.The cloned request (
authReq) is then passed to the next handler in the chain usingreturn next.handle(authReq);. Thepipeoperator allows you to chain RxJS operators. In this case,mapis used to map the response to itself (which is optional in this context).catchErroris used to catch and handle any errors that might occur during the request.The interceptor includes an optional private method (
handleError) to handle errors. This method is called within thecatchErroroperator.
Register the Interceptor
// app.module.ts
import { NgModule } from '@angular/core';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { AuthInterceptor } from './auth.interceptor';
@NgModule({
declarations: [/* your components */],
imports: [HttpClientModule],
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: AuthInterceptor,
multi: true
}
],
bootstrap: [/* your root component */]
})
export class AppModule { }
Explanation:
In your
app.module.tsfile, you import the necessary modules and theAuthInterceptorclass.The
HTTP_INTERCEPTORStoken is used to provide a list of interceptors. In this case, you provide theAuthInterceptorusing theuseClassproperty.The
multi: trueoption indicates that you're providing multiple interceptors.
In conclusion, Angular interceptors serve as essential tools in optimizing your application's interaction with the server. As you navigate your Angular projects, consider interceptors as reliable companions, adept at simplifying common challenges.


