An excellent method for managing and altering HTTP requests and answers across your application is to use Angular interceptors. Although classes are typically used to build interceptors, function-based interceptors can be used for more straightforward and reusable code.


We'll go over how to make and use function-based interceptors in Angular in this blog, along with simple examples for increased flexibility and clarity.

What is a function-based Interceptor?
A function-based interceptor is a simpler and more flexible option compared to a class-based interceptor. Instead of creating a whole class with an intercept method, you put your logic into individual functions. This approach helps with,

  • Separation of Concerns: Smaller, focused functions are easier to test and maintain.
  • Reusability: You can reuse the interceptor logic by sharing or combining multiple functions.

Benefits of Function-Based Interceptors

  • Less Setup: You only need a function, not an entire class.
  • Easier Testing: It’s simpler to test individual functions.
  • Flexible: You can combine several functions to handle complex request/response processes.

How to implement a function-based Interceptor?
Let us create an angular project with the imported HttpClientModule.
    import { NgModule } from '@angular/core';
    import { BrowserModule } from '@angular/platform-browser';
    import { HttpClientModule } from '@angular/common/http';
    import { AppComponent } from './app.component';

    @NgModule({
      declarations: [AppComponent],
      imports: [BrowserModule, HttpClientModule],
      bootstrap: [AppComponent]
    })
    export class AppModule { }

TypeScript
Create a function-based interceptor - a function-based interceptor works by using a factory to handle the request/response logic.

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

export const authInterceptor: HttpInterceptorFn = (req, next) => {
  console.log('Intercepting Request:', req);

  // Add an Authorization header
  const token = 'your-token-here';
  const clonedRequest = req.clone({
    setHeaders: {
      Authorization: `Bearer ${token}`,
    },
  });

  console.log('Modified Request:', clonedRequest);

  // Forward the modified request
  return next(clonedRequest);
};


Key Points

  • Factory Function: Use HttpInterceptorFn to define the interceptor.
  • Modify Request: Use req.clone() to create a modified version of the request.
  • Forward Request: Send the cloned request to the next step with next.

Register the Function Interceptor
To register the function-based interceptor, use the provided HTTP client configuration in your AppModule or feature module.
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HttpClientModule, provideHttpClient, withInterceptors } from '@angular/common/http';
import { authInterceptor } from './auth-interceptor.fn';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    HttpClientModule
  ],
  providers: [
    provideHttpClient(withInterceptors([authInterceptor]))
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

Why Use provideHttpClient?
Introduced in Angular 15, this modern API makes it easier to configure the HTTP client and supports function-based interceptors directly.

Use the Interceptor in an HTTP Request

Now that the interceptor is registered test it by making an HTTP request.
import { HttpClient } from '@angular/common/http';
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  title = 'function-based-Interceptor';

  constructor(private http: HttpClient) { }

  ngOnInit(): void {
    this.http.get('https://jsonplaceholder.typicode.com/posts').subscribe((data) => {
      console.log('Response:', data);
    });
  }
}


Let us execute the app and validate whether the interceptor was properly executed.