Tutorials Logic, IN +91 8092939553 info@tutorialslogic.com
FAQs Support
Navigation
Home About Us Contact Us Blogs FAQs
Tutorials
All Tutorials
Services
Academic Projects Resume Writing Interview Questions Website Development
Compiler Tutorials

HTTP Interceptors in Angular

What are Interceptors?

HTTP interceptors sit between your application and the server. They can inspect, transform, or handle every outgoing request and incoming response — perfect for adding auth tokens, logging, error handling, or loading indicators.

Angular 15+ supports functional interceptors — a simpler, more tree-shakeable alternative to class-based interceptors.

Auth Token Interceptor

Auth Interceptor
import { HttpInterceptorFn } from '@angular/common/http';
import { inject } from '@angular/core';
import { AuthService } from './auth.service';

export const authInterceptor: HttpInterceptorFn = (req, next) => {
    const auth = inject(AuthService);
    const token = auth.getToken();

    if (token) {
        const authReq = req.clone({
            headers: req.headers.set('Authorization', `Bearer ${token}`)
        });
        return next(authReq);
    }

    return next(req);
};
import { ApplicationConfig } from '@angular/core';
import { provideHttpClient, withInterceptors } from '@angular/common/http';
import { authInterceptor } from './auth.interceptor';
import { loggingInterceptor } from './logging.interceptor';

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

Logging Interceptor

Logging Interceptor
import { HttpInterceptorFn } from '@angular/common/http';
import { tap, finalize } from 'rxjs/operators';

export const loggingInterceptor: HttpInterceptorFn = (req, next) => {
    const start = Date.now();
    console.log(`[HTTP] ${req.method} ${req.url}`);

    return next(req).pipe(
        tap({
            next: response => console.log(`[HTTP] Response:`, response),
            error: err => console.error(`[HTTP] Error:`, err)
        }),
        finalize(() => {
            const duration = Date.now() - start;
            console.log(`[HTTP] ${req.url} completed in ${duration}ms`);
        })
    );
};

Error Handling Interceptor

Error Interceptor
import { HttpInterceptorFn, HttpErrorResponse } from '@angular/common/http';
import { inject } from '@angular/core';
import { catchError, throwError } from 'rxjs';
import { Router } from '@angular/router';
import { NotificationService } from './notification.service';

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

    return next(req).pipe(
        catchError((error: HttpErrorResponse) => {
            switch (error.status) {
                case 401:
                    router.navigate(['/login']);
                    break;
                case 403:
                    notify.error('You do not have permission.');
                    break;
                case 404:
                    notify.error('Resource not found.');
                    break;
                case 500:
                    notify.error('Server error. Please try again later.');
                    break;
                default:
                    notify.error(`Unexpected error: ${error.message}`);
            }
            return throwError(() => error);
        })
    );
};

Loading Indicator Interceptor

Loading Interceptor
import { HttpInterceptorFn } from '@angular/common/http';
import { inject } from '@angular/core';
import { finalize } from 'rxjs/operators';
import { LoadingService } from './loading.service';

export const loadingInterceptor: HttpInterceptorFn = (req, next) => {
    const loading = inject(LoadingService);
    loading.show();

    return next(req).pipe(
        finalize(() => loading.hide())
    );
};
import { Injectable, signal } from '@angular/core';

@Injectable({ providedIn: 'root' })
export class LoadingService {
    private _count = signal(0);
    readonly isLoading = this._count.asReadonly();

    show() { this._count.update(n => n + 1); }
    hide() { this._count.update(n => Math.max(0, n - 1)); }
}

Ready to Level Up Your Skills?

Explore 500+ free tutorials across 20+ languages and frameworks.