Here is a working example of how I have set up an interceptor which attaches an authentication token to each request (this is more or less the example from https://docs.angularjs.org/api/ng/service/$http)
angular.module("app", [])
.config(function ($httpProvider) {
$httpProvider.interceptors.push("authInterceptor");
})
.factory("authInterceptor", function ($q) {
return {
// interceptor configuration here
}
})
I have a lot of other stuff in my config
and run
blocks which call and initiate services from different angular modules, so I want to tidy things up a bit. However I understand there are some very specific rules to dependency injection in config
blocks, which I don't quite understand, and these are preventing me from defining my authInterceptor
factory in a separate module. As other logic in the config
and run
blocks calls other modules in the app, declaring that interceptor right there looks out of place.
This is what I want to do:
angular.module("services.authInterceptor", [])
.factory("authInterceptor", function ($q) {
return {
// interceptor configuration here
}
});
angular.module("app", [
"services.authInterceptor"
]).config(function ($httpProvider, authInterceptor) {
$httpProvider.interceptors.push("authInterceptor");
});
// Error: Unknown provider authInterceptor.
I tried injecting it to the run
block instead, but I guess you're not allowed to inject $httpProvider
there:
angular.module("app", [
"services.authInterceptor"
]).run(function ($httpProvider, authInterceptor) {
$httpProvider.interceptors.push("authInterceptor");
});
// Error: Unknown provider: $httpProviderProvider <- $httpProvider
Where should I inject the module so that $httpProvider
is also injectable, and where should I add the interceptor to existing ones? My main goal is keeping the interceptor and other similar services in their own self-containing modules.
EDIT
I get a different error which seems to be getting me closer when I declare a provider
instead of factory
(for some reason I always thought these were interchangeable):
angular.module("services.authInterceptor")
.provider("authInterceptor", function ($q) {
return {}
})
// Error: Unknown provider: $q
So it now successfully injects authInterceptor
to my config
block, but fails when trying to find $q
.
During the configuration phase only providers and constants can be injected. This is to prevent instantiation of services before they have been fully configured.
This is why you register interceptors by name (pushing the name as a string into the $httpProvider.interceptors
array). They will be resolved later during runtime.
This is exactly what you did in your working example, and what you need to do in your second, even when the interceptor is in another module:
angular.module("services.authInterceptor", [])
.factory("authInterceptor", function ($q) {
return {
// interceptor configuration here
}
});
angular.module("app", ["services.authInterceptor"])
.config(function ($httpProvider) {
$httpProvider.interceptors.push('authInterceptor');
});