Reputation: 2735
In my app I need to inject "dateFilter" in the config
block. I know I can't do it like this:
.config(function(dateFilter){})
Since dateFilter
is not a provider or a constant, it's not available during config
.
However, after some research, I made it work by using the following in the config
:
angular.injector(["ng"]).get('dateFilter')('2014-01-01','yyyy/MM/dd');
Doesn't this mean that I can get anything during config
? Then what's the point making only providers
and constants
injectable during config
? Is it bad to do something like angular.injector(["ng"]).get('dateFilter')
during config
?
Upvotes: 2
Views: 1313
Reputation: 222344
angular.injector
shouldn't be used in production, unless the circumstances are really exotic (i.e. almost never). It creates a new injector instance and introduces some overhead. Conventional Angular DI is good for its testability, while angular.injector
turns a part of the application into untestable piece of code. Always reuse current injector inside the app, if possible (i.e. almost always).
Usually 'how to use service instance in config block' type of questions indicates an XY problem. The fact that Angular uses config
to configure service providers that thereafter will create service instances (chicken-egg dilemma) suggests that the application should be refactored to respect Angular life cycle.
However, built-in filters are stateless helper functions, and their use in config phase is relatively harmless. dateFilter
service is defined by $filterProvider
, and $filterProvider
should be injected to get to dateFilterProvider
. The problem is that dateFilter
depends on $locale
service, which wasn't instantiated yet. $locale
is constant (in broad sense) that doesn't depend on other services, so it has to be instantiated too.
angular.module('...', [
'ngLocale' // if used, should be loaded in this module
])
.config(($filterProvider, $localeProvider, $provide, $injector) => {
var $locale = $injector.invoke($localeProvider.$get);
var dateFilterProvider = $injector.get('dateFilterProvider')
var dateFilter = $injector.invoke(dateFilterProvider.$get, { $locale: $locale });
$provide.constant('dateHelper', dateFilter);
})
This is a hack should be taken into account in tests (dateHelper
service should superficially tested) but is relatively trouble-free and idiomatic.
Upvotes: 1
Reputation: 300
you cant inject services in config only provides but you can do it in app.run here's the calling order:
Upvotes: 0