Migrating Angular Interceptors to Function-Based Interceptors: A Step-by-Step Guide
Class-based interceptors for handling HTTP requests and responses has been a very useful Angular feature. However, Angular 14 introduced a more functional approach, allowing us to use function-based interceptors. This can simplify our code and make it more readable. In this blog post, we'll walk through the process of migrating from traditional class-based interceptors to function-based interceptors.
What Are Interceptors?
Interceptors are a powerful feature in Angular that allows you to intercept and modify HTTP requests and responses. They can be used for a variety of tasks such as adding authentication tokens, logging, error handling, and more.
Traditional Class-Based Interceptors
Let's start with an example of a traditional class-based interceptor which intercepts each http-request injects token:
import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const authToken = 'your-auth-token';
const authReq = req.clone({
headers: req.headers.set('Authorization', `Bearer ${authToken}`)
});
return next.handle(authReq);
}
}
In this example, the AuthInterceptor
class implements the HttpInterceptor
interface, and the intercept
method is used to modify the request by adding an authorization token to the headers.
Migrating to Function-Based Interceptors
Below is a step-by-step guide for migration.
Step 1: Creating the Function-Based Interceptor
First, let's rewrite the above class-based interceptor as a function:
import { HttpInterceptorFn } from '@angular/common/http';
export const authInterceptor: HttpInterceptorFn = (req, next) => {
const authToken = 'your-auth-token';
const authReq = req.clone({
headers: req.headers.set('Authorization', `Bearer ${authToken}`)
});
return next(authReq);
};
In this function-based interceptor, we create an authInterceptor
function that takes req
(the request) and next
(the next handler) as parameters. We modify the request to include the authorization token and then pass it to the next handler.
Step 2: Registering the Function-Based Interceptor
To use this function-based interceptor in your Angular application, you need to provide it in the module configuration. Modify your app.module.ts
as follows:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule, provideHttpClient, withInterceptors } from '@angular/common/http';
import { AppComponent } from './app.component';
import { authInterceptor } from './auth.interceptor';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
HttpClientModule
],
providers: [
provideHttpClient(
withInterceptors([authInterceptor])
),
],
bootstrap: [AppComponent]
})
export class AppModule { }
In this setup, we use provideHttpClient
to register the authInterceptor
function as an HTTP interceptor.
Step 3: Testing the Function-Based Interceptor
Run the application and verify that the Authorization
header is correctly added.
Advantages over class-based interceptor:
1. Ease of use
2. Easy configuration