
In today’s fast-paced web development world, handling data efficiently can make or break your application. With Angular 19, one feature that stands out for streamlining HTTP requests and responses is the HTTP Interceptor. Whether you’re securing APIs, managing errors globally, or showing loaders during network calls, interceptors offer a clean and scalable solution.
Let’s dive into how you can harness the full potential of Angular Interceptors to write smarter and more maintainable code.
🚦 What Are Angular Interceptors?
Think of interceptors as middleware between your frontend and backend. Every HTTP request your app makes passes through them. That means you get a golden opportunity to:
- Read or modify outgoing requests
- Handle incoming responses
- Catch and manage errors in one place
💡 Why Use Interceptors?
Here’s what you can achieve with a well-structured interceptor:
- Inject Auth Tokens: Seamlessly attach JWTs or API keys to every request
- Global Error Handling: Catch and process errors from a central location
- API Response Caching: Avoid duplicate API calls and enhance performance
- Show/Hide Loaders: Improve UX by showing loading indicators
- Log Traffic: Track, debug, and analyze requests & responses
🛠️ Creating a Custom Interceptor in Angular 19
Step 1: Generate the Interceptor Service
Use Angular CLI to scaffold the interceptor:
ng generate service interceptors/http
Step 2: Implement HttpInterceptor
Interface
Update the generated service file (http.interceptor.ts
) like so:
import { Injectable } from '@angular/core';
import {
HttpInterceptor,
HttpRequest,
HttpHandler,
HttpEvent
} from '@angular/common/http';
import { Observable } from 'rxjs';
import { finalize } from 'rxjs/operators';
@Injectable()
export class HttpInterceptorService implements HttpInterceptor {
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const authToken = 'YOUR_AUTH_TOKEN'; // Replace with your dynamic token
const modifiedReq = request.clone({
setHeaders: {
Authorization: `Bearer ${authToken}`,
},
});
console.log('Outgoing request:', modifiedReq);
return next.handle(modifiedReq).pipe(
finalize(() => {
console.log('Request completed');
})
);
}
}
Step 3: Register Your Interceptor in the Module
Make sure to add it in your AppModule
:
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { HttpInterceptorService } from './interceptors/http.interceptor';
@NgModule({
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: HttpInterceptorService,
multi: true,
},
],
})
export class AppModule {}
🛡️ Handling Errors Globally
Want consistent error handling without cluttering each HTTP call? Add catchError
:
import { catchError } from 'rxjs/operators';
import { throwError } from 'rxjs';
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(request).pipe(
catchError((error) => {
console.error('Error caught by interceptor:', error);
return throwError(() => new Error('An unexpected error occurred'));
})
);
}
✅ Practical Use Cases
1. Injecting Auth Tokens Automatically
Attach tokens dynamically without repeating code:
const token = this.authService.getToken(); // Assume a method that fetches token
const authReq = request.clone({
setHeaders: {
Authorization: `Bearer ${token}`,
},
});
2. Managing Loading Indicators
Show a loading spinner while requests are in progress:
import { Subject } from 'rxjs';
export class LoaderService {
isLoading = new Subject<boolean>();
}
// Inside the interceptor:
this.loaderService.isLoading.next(true);
return next.handle(request).pipe(
finalize(() => this.loaderService.isLoading.next(false))
);
🧠 Final Thoughts
Angular 19 Interceptors are one of the most underrated yet powerful features of the framework. They help you:
- Centralize critical logic like authentication and error handling
- Improve maintainability
- Enhance the overall user experience
If you’re serious about building scalable Angular apps, mastering interceptors is a must. Start small—inject tokens, show a loader, or handle a simple error—and soon you’ll be intercepting your way to cleaner, smarter codebases.