October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsPC HealthRecommendedCrashes, freezes, slowdowns? Check your PC nowSpot repairable issues before they interrupt work.Check PCOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk5 min

How to Intercept HTTP Requests and Responses in Angular

Angular interceptors apply shared behavior around HttpClient calls. Learn functional registration, safe request cloning, response and error handling, and testing.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Angular interceptors let you apply shared behavior around HttpClient calls: add or scope authentication headers, log traffic, handle errors, retry requests, or observe responses. For new applications, Angular recommends functional interceptors registered with provideHttpClient(withInterceptors([...])). Clone requests rather than changing them in place, and treat the result of next(req) as an event stream—not as a single response.

How Angular interceptors work

An interceptor sits between an HttpClient call and the next handler in the HTTP pipeline. It receives an outgoing HttpRequest and a next function. It can forward the request unchanged, forward a modified clone, transform the response event stream, or—in cases such as a cache hit—return a response without forwarding the request.

As an Amazon Associate I earn from qualifying purchases.

Interceptors run in the order they are registered on the way out. Responses travel back through the chain in reverse order. This makes registration order important when one interceptor depends on another—for example, when logging should see a request after an authentication header has been added.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Register a functional interceptor

Functional interceptors are Angular’s recommended option for predictable behavior, especially in complex configurations. Register them in the application’s providers with provideHttpClient and withInterceptors:

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

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

The listed order is the outgoing request order. A functional interceptor runs in the injection context of the injector where it was registered, so it can use Angular’s inject() function to obtain services.

Add an authentication header safely

Use req.clone() to create the request with updated headers. The service and header below are illustrative; use the credential source and header expected by your API.

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

export const authInterceptor: HttpInterceptorFn = (req, next) => {
  const authToken = inject(AuthService).getAuthToken();

  const authenticatedReq = req.clone({
    headers: req.headers.set('X-Authentication-Token', authToken),
  });

  return next(authenticatedReq);
};

Do not attach a secret to every request automatically. Restrict credentials to the API origins and paths that are meant to receive them. A broadly registered interceptor may also see requests to unrelated services, such as an image host or a third-party API.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Requests and responses are mostly immutable: update them by cloning, and use immutable header or parameter APIs such as set() and append(). Their bodies are not deeply immutable, however. Avoid changing an object body in place; if the request is retried, the same interceptor can run again and observe the already-mutated body.

Choose between functional and class-based interceptors

Approach Registration When it fits
Functional provideHttpClient(withInterceptors([myInterceptor])) Recommended for new code and for configurations where predictable ordering matters.
Class-based, DI-provided Register a class with the HTTP_INTERCEPTORS multi-provider, then enable it with withInterceptorsFromDi(). Useful when retaining an existing class-interceptor setup. Angular continues to support this approach, though ordering can be harder to predict in extensive or hierarchical dependency-injection configurations.

A class interceptor implements HttpInterceptor and defines an intercept(req, next) method. If you use this form, include both the multi-provider registration and withInterceptorsFromDi() in the HTTP client setup; registering the class alone is not the complete configuration.

Read responses without confusing them with other events

An interceptor’s next(req) returns an Observable of HttpEvent values. Depending on the request and configuration, that stream can include progress or other lifecycle events as well as the final response. Check the event type before accessing response-specific fields:

import { HttpEventType, HttpInterceptorFn } from '@angular/common/http';
import { tap } from 'rxjs';

export const responseLoggerInterceptor: HttpInterceptorFn = (req, next) =>
  next(req).pipe(
    tap(event => {
      if (event.type === HttpEventType.Response) {
        console.log('HTTP status:', event.status);
      }
    }),
  );

Use an interceptor’s event stream when you need cross-cutting observation or transformation. In ordinary application code, HttpClient returns the response body by default. Set observe: 'response' on a request when its caller needs the full response object, including status and headers.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Handle errors in the Observable error channel

HTTP failures do not arrive as successful response events. Angular reports them through the Observable error channel as HttpErrorResponse. A network or connection failure and a configured timeout use status 0; a backend error carries the status returned by the server. An interceptor can apply shared handling with RxJS operators, while allowing callers to receive the error when appropriate.

import { HttpErrorResponse, HttpInterceptorFn } from '@angular/common/http';
import { catchError, throwError } from 'rxjs';

export const errorLoggingInterceptor: HttpInterceptorFn = (req, next) =>
  next(req).pipe(
    catchError((error: HttpErrorResponse) => {
      console.error('Request failed:', error.status, error.message);
      return throwError(() => error);
    }),
  );

Logging and rethrowing preserves the failure for request-specific code to handle. If an interceptor instead converts an error into a successful fallback value, callers will observe that fallback as success; use that behavior only when it is intentional.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Use context for interceptor-only metadata

When an interceptor needs per-request instructions that should not become an HTTP header or query parameter, use a typed HttpContextToken. The context is mutable even though most request fields are immutable, so context state can persist when a request is retried. Account for that persistence when storing flags or retry-related metadata.

Return a synthetic response only when bypassing the chain is intended

An interceptor can return an HttpResponse directly—for example, when a cache can satisfy a request—without calling next(req). This stops the request from reaching the backend and also skips every downstream interceptor. Consider the chain order before using this pattern: any downstream logging, transformation, or error behavior will not run for the synthetic response.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Test an interceptor with Angular’s HTTP testing utilities

Test the behavior one interceptor at a time: configure the HTTP client with the interceptor under test, make a request, capture it with HttpTestingController, assert the changed request fields, and then flush a representative result. Use the testing controller’s network-error mechanism for a connection failure.

import { TestBed } from '@angular/core/testing';
import {
  provideHttpClient,
  withInterceptors,
} from '@angular/common/http';
import {
  HttpTestingController,
  provideHttpClientTesting,
} from '@angular/common/http/testing';

beforeEach(() => {
  TestBed.configureTestingModule({
    providers: [
      provideHttpClient(withInterceptors([authInterceptor])),
      provideHttpClientTesting(),
    ],
  });
});

afterEach(() => {
  TestBed.inject(HttpTestingController).verify();
});

In a test, inject HttpClient and HttpTestingController, subscribe to the request, then use expectOne() to capture it. Assert the relevant header or other modification on the captured request. Call flush() with a success or backend error to test those paths; use error() with a ProgressEvent to simulate a network error. Verify outstanding requests are cleared so a test cannot pass while leaving an unexpected call behind.

Official Angular references

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

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

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Windows Errors? Fix Them Before They SpreadFree repair scan
Outdated Drivers Are Slowing You DownFree scan - exact matches

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.