Angular Interceptors

An interceptor is a piece of code that sits between your application and the server. Every web request passes through it on the way out, and every response passes through it on the way back. You write the logic once, and it applies to all requests. Adding a login token to every call is the most common use.

The Security Desk Idea

Think of the reception desk in an office building. Every visitor stops at the desk. The guard checks a badge, adds a visitor pass, and records the entry. Visitors leave through the same desk. An interceptor acts as that desk for your HTTP calls.

 Component
     |  request
     v
+----------------+
|  Interceptor   |  adds token, logs, or changes the request
+----------------+
     |
     v
   Server
     |  response
     v
+----------------+
|  Interceptor   |  checks errors or changes the response
+----------------+
     |
     v
 Component

Why Use Interceptors

Without an interceptor, each service must add the same header by hand. Copy and paste leads to missed spots and bugs. One interceptor removes this repetition. A future change, such as a new header name, needs an edit in one file only.

Create a Functional Interceptor

Modern Angular uses a plain function for an interceptor. The function receives the request and a next handler. Requests are read-only, so you clone the request to change it.

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

export const authInterceptor: HttpInterceptorFn = (req, next) => {
  const token = localStorage.getItem('token');

  const securedRequest = req.clone({
    setHeaders: { Authorization: `Bearer ${token}` }
  });

  return next(securedRequest);
};

The clone call creates a copy with the new header. The next call passes the copy forward to the server.

Register the Interceptor

Add the function to the HTTP provider in your app configuration.

import { provideHttpClient, withInterceptors } from '@angular/common/http';

export const appConfig = {
  providers: [
    provideHttpClient(withInterceptors([authInterceptor]))
  ]
};

The list accepts several interceptors. Angular runs them in the order you list them.

Handle Errors in One Place

An interceptor can watch responses and react to failures. The code below catches an unauthorized response and sends the visitor to the login page.

import { inject } from '@angular/core';
import { Router } from '@angular/router';
import { catchError, throwError } from 'rxjs';

export const errorInterceptor: HttpInterceptorFn = (req, next) => {
  const router = inject(Router);

  return next(req).pipe(
    catchError(error => {
      if (error.status === 401) {
        router.navigate(['/login']);
      }
      return throwError(() => error);
    })
  );
};

Show a Loading Indicator

A loading interceptor tracks active requests. It turns a spinner on when a request starts and turns it off when the response arrives. Every screen in the app benefits from one shared spinner without extra code in each service.

Common Interceptor Uses

UseWhat It Does
AuthenticationAdds a token to each request
Error handlingReacts to failed responses in one place
LoggingRecords requests for debugging
Loading indicatorShows a spinner during requests
CachingReuses earlier answers for repeated calls

Order of Execution

Interceptors form a chain. The first interceptor in the list touches the request first and the response last. Picture a set of nested boxes. The request travels inward through each box, reaches the server, and returns outward through the same boxes in reverse order. Plan the order with care. Place the logging interceptor first if you want to record the original request, and place the error interceptor last if you want it to see the raw server answer.

Testing an Interceptor

Angular provides a testing tool that fakes server calls. Send a fake request through your interceptor and inspect the headers on the result. This approach confirms the token appears without any real server.

Tips for Interceptors

Keep each interceptor focused on one job. Skip adding tokens to calls that go to other websites, because you should never share your private token with outside servers. Test each interceptor with a mock request before you trust it in production.

Key Points

  • An interceptor handles every request and response in one place.
  • Clone a request before you change it.
  • Register interceptors with withInterceptors.
  • Use interceptors for tokens, errors, logging, and loading indicators.

Leave a Comment

Your email address will not be published. Required fields are marked *