Skip to main content

HTTP Interceptors

Level: Intermediate

ℹ️ What You'll Learn
  • What interceptors do
  • Request interceptor (add headers)
  • Response/error interceptor
  • Auth token handling
  • Global error handling

Basic Interceptor

import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';

@Injectable()
export class AuthInterceptor implements HttpInterceptor {
constructor(private auth: AuthService) {}

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
// Add auth token to request
const token = this.auth.getToken();

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

return next.handle(req);
}
}

Register in config:

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

Functional Interceptor (Modern)

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

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

return next(req);
};

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

Error Interceptor

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

return next(req).pipe(
catchError((error: HttpErrorResponse) => {
if (error.status === 401) {
// Unauthorized - logout
auth.logout();
router.navigate(['/login']);
} else if (error.status === 403) {
// Forbidden
alert('Access denied');
} else if (error.status === 500) {
// Server error
console.error('Server error:', error);
}

return throwError(() => error);
})
);
};

Multiple Interceptors

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

Executed in order: auth → error → logging.

Logging Interceptor

export const loggingInterceptor: HttpInterceptorFn = (req, next) => {
const startTime = Date.now();

return next(req).pipe(
tap(() => {
const elapsed = Date.now() - startTime;
console.log(`${req.method} ${req.url} in ${elapsed}ms`);
})
);
};

SMS Interceptor Example

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

// Add auth and school context
if (token) {
req = req.clone({
setHeaders: {
'Authorization': `Bearer ${token}`,
'X-School-Id': schoolId
}
});
}

return next(req).pipe(
catchError((error: HttpErrorResponse) => {
if (error.status === 401) {
// Token expired - refresh
return auth.refreshToken().pipe(
switchMap(() => {
const newToken = auth.getToken();
const newReq = req.clone({
setHeaders: { 'Authorization': `Bearer ${newToken}` }
});
return next(newReq);
}),
catchError(() => {
auth.logout();
window.location.href = '/login';
return throwError(() => error);
})
);
}

return throwError(() => error);
})
);
};

Key Takeaways

  • Interceptors = global HTTP middleware
  • Intercept requests (add headers)
  • Intercept responses (handle errors)
  • Add auth tokens automatically
  • Global error handling
  • Multiple interceptors chain together
💡 Backend Developer Tip

Interceptors similar to middleware pipeline in ASP.NET. Request flows through all interceptors before reaching server.

⚠️ Interceptor Issues
  1. Circular dependency — Interceptor uses HTTP client
  2. Token not refreshed — Expired tokens not handled
  3. Wrong order — Interceptors executed in wrong order
  4. Infinite loops — Interceptor calls API infinitely
🤖Use AI to Learn Faster

Use ChatGPT, Claude, or Copilot to go deeper on Interceptors. Try these prompts:

  • "Why use interceptors instead of per-request headers?"
  • "How do you refresh expired tokens?"
  • "What's difference between request and error interceptor?"
  • "Quiz me on interceptors"

💡 Tip: After reading this article, paste your own code into AI and ask "What could go wrong here and why?" — fastest way to find edge cases and deepen understanding.

nexcoding.in