If $httpInterceptor
(or more accurately, $httpInterceptor
as part of AngularJS’s $httpProvider.interceptors
) is not intercepting requests correctly, there are several possible reasons. Let’s walk through how $httpInterceptor
works, what can go wrong, and how to troubleshoot and fix it step-by-step.
What is $httpInterceptor
?
In AngularJS (1.x), $httpInterceptor
is used to intercept all HTTP requests and responses. It’s often used for:
- Adding headers like authentication tokens
- Logging or transforming requests/responses
- Handling errors like 401 Unauthorized globally
Basic Structure of an $httpInterceptor
Here’s how a typical interceptor looks:
app.factory('myInterceptor', function($q) {
return {
request: function(config) {
// Modify request here
return config;
},
response: function(response) {
// Modify response here
return response;
},
responseError: function(rejection) {
// Handle error
return $q.reject(rejection);
}
};
});
app.config(function($httpProvider) {
$httpProvider.interceptors.push('myInterceptor');
});
Common Reasons It’s Not Working
1. Interceptor Not Registered
If you forget to push your interceptor to $httpProvider.interceptors
, it will never be used.
Fix: Ensure you have this in your module configuration:
$httpProvider.interceptors.push('myInterceptor');
2. Wrong Dependency Injection
If you inject $httpProvider
incorrectly or use the interceptor name wrong, it won’t be recognized.
Fix: Check that your factory name matches the one pushed:
.factory('myInterceptor', ...)
and
$httpProvider.interceptors.push('myInterceptor');
Names must match exactly.
3. Interceptor Factory Not Returning Proper Object
Your interceptor must return an object with at least one of these functions:
request
requestError
response
responseError
If not, the interceptor silently fails.
Fix: Make sure your factory returns the interceptor object.
Example:
return {
request: function(config) {
// do something
return config;
},
responseError: function(rejection) {
return $q.reject(rejection);
}
};
4. Request Bypassing $http
If your app uses custom AJAX via XMLHttpRequest
, fetch
, or some external library like Axios or jQuery’s $.ajax
, those requests won’t go through AngularJS’s $http
, and won’t be intercepted.
Fix: Make sure your HTTP calls are made using $http
, $resource
, or $httpBackend
.
Example:
$http.get('/api/data') // will be intercepted
fetch('/api/data') // will not be intercepted
5. Wrong Interceptor Scope
The interceptor should be added in the module config phase, not run phase.
Fix:
app.config(function($httpProvider) {
$httpProvider.interceptors.push('myInterceptor');
});
Don’t put it inside .run()
or outside the config block.
6. Circular Dependency
If your interceptor injects a service that itself depends on $http
, it will cause a circular dependency and your interceptor won’t run.
Fix: Use $injector
to lazily inject dependencies inside the interceptor.
Bad:
.factory('myInterceptor', function(MyService) { ... }) //
Good:
.factory('myInterceptor', function($q, $injector) {
return {
request: function(config) {
var MyService = $injector.get('MyService');
// safe to use now
return config;
}
};
})
7. CORS or OPTIONS Requests Not Being Intercepted
Browsers make preflight OPTIONS
requests for CORS. These are not intercepted by AngularJS $http
because they’re handled by the browser automatically.
Fix: You can only intercept the actual request (GET
, POST
, etc.), not preflight OPTIONS
requests.
Debugging Tips
- Console Logging: Inside each function (
request
,response
, etc.), add console logs to verify they are being hit.
request: function(config) {
console.log('Intercepted Request:', config);
return config;
}
- Check Order: Interceptors run in the order they are pushed. Double-check if another interceptor is affecting yours.
- Use Browser Dev Tools: Open the Network tab to ensure your HTTP request is made by
$http
and isn’t being blocked or errored before Angular can intercept.
Sample Working Code
angular.module('myApp', [])
.factory('authInterceptor', function($q, $injector) {
return {
request: function(config) {
const AuthService = $injector.get('AuthService');
const token = AuthService.getToken();
if (token) {
config.headers['Authorization'] = 'Bearer ' + token;
}
return config;
},
responseError: function(response) {
if (response.status === 401) {
const $state = $injector.get('$state');
$state.go('login');
}
return $q.reject(response);
}
};
})
.config(function($httpProvider) {
$httpProvider.interceptors.push('authInterceptor');
});
Final Checklist
- Interceptor factory is correctly defined and named
- Interceptor is pushed inside
app.config()
- You use
$http
for your requests - Factory returns a valid object with hook methods
- No circular dependency exists
- You’re not trying to intercept non-Angular HTTP calls