Angular HTTP Interceptors
Learn Angular HTTP Interceptors, including HttpInterceptorFn, provideHttpClient, withInterceptors, request cloning, JWT auth, refresh tokens, loading and logging, error handling, retry, caching, deduplication, correlation IDs, HttpContext, ordering, enterprise architecture, security, and interview questions.
Learning Objectives
By the end of this lesson, you will understand:
- What HTTP Interceptors are.
- Why Angular uses Interceptors.
- How the HTTP request lifecycle works.
- Functional Interceptors (
HttpInterceptorFn). - Class-based Interceptors.
provideHttpClient().withInterceptors().- Request and Response interception.
- Immutable HttpRequest.
- Request cloning.
- JWT Authentication.
- Authorization headers.
- Refresh Token architecture.
- Global Error Handling.
- Retry strategies.
- Logging Interceptor.
- Loading Spinner Interceptor.
- Correlation IDs.
- Request Timing.
- Request Caching.
- Request Deduplication.
- HTTP Context.
- Interceptor ordering.
- Enterprise architecture.
- Performance optimization.
- Security best practices.
- Advanced interview questions.
Introduction
Imagine TechLearningPro.
Whenever a student opens:
Angular Course
Angular sends:
GET /api/courses/angular
Before sending the request, the application must:
- Add JWT Token
- Add User ID
- Add Language
- Add Correlation ID
- Show Loading Spinner
- Log Request
- Measure Response Time
After receiving the response:
- Hide Loading Spinner
- Handle Errors
- Refresh Expired Token
- Cache Response
- Update UI
Should every component implement all of this?
No.
Angular provides HTTP Interceptors.
What is an HTTP Interceptor?
An HTTP Interceptor is middleware that executes before a request leaves the application and after a response returns.
Architecture
Component↓HttpClient↓Interceptor 1↓Interceptor 2↓Interceptor 3↓Backend API↓Interceptor 3↓Interceptor 2↓Interceptor 1↓Component
Interceptors sit between your application and the backend.
Why Use Interceptors?
Without Interceptors:
Course Component↓Add JWT↓Show Loader↓Handle Error↓API↓Hide Loader
Every component repeats the same logic.
With Interceptors:
Course Component↓HttpClient↓Interceptors↓Backend
Components remain clean and focused on business logic.
HTTP Request Lifecycle
Component↓HttpClient↓Authentication Interceptor↓Logging Interceptor↓Loading Interceptor↓Backend API↓Response↓Error Handler↓Component
Every request follows this pipeline.
Functional Interceptors
Modern Angular recommends functional interceptors.
Example:
export const authInterceptor: HttpInterceptorFn = (req,next) => {return next(req);};
Benefits:
- Simpler syntax
- Better tree-shaking
- Easier testing
- Works naturally with standalone Angular
Registering Interceptors
Register them during bootstrap.
bootstrapApplication(AppComponent, {providers: [provideHttpClient(withInterceptors([authInterceptor,loggingInterceptor]))]});
Architecture
Bootstrap↓HttpClient↓Interceptors Registered
Request Flow
Component↓GET /courses↓Interceptor↓Modify Request↓Backend
HttpRequest is Immutable
This is one of the most important interview questions.
You cannot modify:
req.headers.set(...)
Instead:
const modified =req.clone({headers:req.headers.set('Authorization','Bearer token')});
Then:
return next(modified);
Why Clone?
Architecture
Original Request↓Clone↓Modified Request↓Backend
Immutability prevents accidental side effects.
Authentication Interceptor
Suppose JWT token exists.
eyJhbGci...
Interceptor:
AuthorizationBearer eyJhbGci...
Architecture
Request↓Auth Interceptor↓JWT Added↓Backend
Every request becomes authenticated automatically.
JWT Flow
Login↓Receive JWT↓Store Securely↓Interceptor Reads Token↓Authorization Header↓Backend
Components never manually attach tokens.
Refresh Token Architecture
Suppose:
JWT Expired
Backend returns:
401 Unauthorized
Architecture
API Request↓401↓Refresh Token API↓New JWT↓Retry Original Request↓Success
Users remain logged in without interruption.
Loading Spinner Interceptor
Instead of showing a spinner in every component:
Architecture
Request Starts↓Loading++↓Spinner Visible↓Response↓Loading--↓Spinner Hidden
A single interceptor controls the global loading indicator.
Logging Interceptor
Every request can be logged.
GET /courses↓Start Time↓Response↓End Time↓Duration
Useful for monitoring slow APIs.
Measuring API Performance
Example:
Request↓10:00:00↓Response↓10:00:01↓1000 ms
Store metrics in monitoring systems.
Global Error Handling
Without Interceptors:
Every component handles errors.
With Interceptors:
Backend↓Error↓Error Interceptor↓Friendly Message↓Component
Centralized error handling.
Handling HTTP Status Codes
Typical strategy:
200 → Success201 → Created400 → Validation Error401 → Authentication403 → Forbidden404 → Not Found500 → Server Error
Interceptors can centralize this mapping.
Retry Strategy
Temporary network failures can often succeed after retrying.
Architecture
Request↓Network Error↓Retry↓Success
Retry only when appropriate (for example, transient failures), and avoid retrying operations that shouldn't be repeated without careful consideration.
Correlation ID
Large enterprise systems assign every request a unique ID.
Example:
X-Correlation-ID↓9d72a3...
Architecture
Request↓Correlation ID↓Backend Logs↓Tracing
This simplifies debugging across distributed services.
HTTP Context
Sometimes an interceptor should ignore specific requests.
Example:
Skip AuthenticationSkip LoadingSkip Cache
Angular's HttpContext allows metadata to travel with a request so interceptors can make these decisions.
Request Caching
Suppose:
GET /courses
called five times.
Instead of:
Browser↓API↓API↓API
Use cache.
Browser↓Cache↓Return Cached Response
This improves performance.
Request Deduplication
Imagine five components requesting:
GET /profile
simultaneously.
Without deduplication:
5 HTTP Calls
With deduplication:
5 Components↓1 HTTP Request↓Shared Response
Useful in enterprise applications.
Response Transformation
Sometimes backend returns:
{"first_name": "Jagannath"}
Interceptor can transform data into a client-friendly format before it reaches the rest of the application.
Interceptor Ordering
Order matters.
Authentication↓Logging↓Caching↓Backend
Responses travel back in reverse order.
Backend↓Caching↓Logging↓Authentication
Plan interceptor order carefully.
Enterprise Interceptor Architecture
HttpClient↓Authentication↓Correlation ID↓Logging↓Loading↓Caching↓Error Handling↓Backend
Each interceptor has a single responsibility.
TechLearningPro Architecture
Student Opens Course↓HttpClient↓JWT Interceptor↓Logging↓Loading↓Backend↓Course Data↓Signals Store↓UI
Performance Best Practices
Prefer:
- Functional Interceptors
- Single Responsibility
- Request cloning
- Caching where appropriate
- Centralized error handling
- Correlation IDs
Avoid:
- Business logic inside Interceptors
- Long-running synchronous work
- Large shared mutable state
- Circular dependencies
Security Best Practices
- Always use HTTPS.
- Never hardcode JWT tokens.
- Don't log sensitive information.
- Validate authorization on the backend.
- Treat client-side authentication as a convenience, not security.
- Protect refresh tokens appropriately.
Common Mistakes
Modifying HttpRequest Directly
Incorrect:
req.headers.set(...)
Correct:
req.clone(...)
Multiple Authentication Implementations
Don't add JWT in every component.
Use one Authentication Interceptor.
One Giant Interceptor
Avoid one interceptor doing:
- Authentication
- Logging
- Retry
- Cache
- Analytics
Split responsibilities.
Infinite Refresh Loop
Always prevent repeated refresh attempts if the refresh endpoint itself fails.
Logging Sensitive Data
Avoid logging:
- Passwords
- Tokens
- Personal information
Especially in production.
Advanced interview questions
Interview Prep
Practice concise answers, then expand each card for the explanation.
1BeginnerQuestionWhat is an HTTP Interceptor?+
Answer
2BeginnerQuestionWhy use Interceptors?+
Answer
- Authentication
- Logging
- Error handling
- Loading indicators
- Caching
- Request modification
3IntermediateQuestionWhy is HttpRequest immutable?+
Answer
4IntermediateQuestionHow do you modify a request?+
Answer
const modified = req.clone({ → headers: req.headers.set('Authorization', 'Bearer token') → }); → return next(modified);5IntermediateQuestionWhat is the difference between Functional and Class Interceptors?+
Answer
- Functional Interceptors (
HttpInterceptorFn) are the modern Angular recommendation. They are concise, tree-shakable, and fit well with standalone APIs. - Class-based Interceptors implement the
HttpInterceptorinterface and remain supported, especially in existing applications.
6BeginnerQuestionWhere are Interceptors registered?+
Answer
provideHttpClient( → withInterceptors([ → authInterceptor → ]) → )7AdvancedQuestionWhat is a Refresh Token flow?+
Answer
8IntermediateQuestionWhy use a Loading Interceptor?+
Answer
9AdvancedQuestionWhat is Request Deduplication?+
Answer
10AdvancedQuestionWhat is the recommended enterprise architecture?+
Answer
Summary
HTTP Interceptors form a middleware pipeline between your Angular application and the backend.
Angular Component│▼HttpClient│▼Authentication Interceptor│▼Correlation ID Interceptor│▼Logging Interceptor│▼Loading Interceptor│▼Caching Interceptor│▼Error Handling Interceptor│▼Backend API│▼Response (Reverse Pipeline)│▼Component
For TechLearningPro, a robust interceptor pipeline automatically authenticates requests, measures performance, handles loading states, manages errors, and improves efficiency through caching and request deduplication—all while keeping components simple.
The key principle: Interceptors should solve one cross-cutting concern each. Keep them small, composable, and reusable to build secure, maintainable, and enterprise-grade Angular applications.
Next Lesson
Angular Forms Advanced — You'll learn:
- Template-driven vs Reactive Forms
- Strongly Typed Forms
- FormControl, FormGroup, FormArray
- Dynamic Forms
- Custom Validators
- Async Validators
- Cross-field Validation
- Nested Forms
- Custom Form Controls (ControlValueAccessor)
- Error handling strategies
- Large enterprise form architecture
- Performance optimization
- Advanced interview questions