-
Notifications
You must be signed in to change notification settings - Fork 27.5k
AngularJS config block causes unknown provider error if provider is added to module after the config block #7139
Comments
I was mistaken when I said that it should work already, config blocks and providers are added to the invoke queue in the order that they're called. This is a bug, in my opinion. It should be easy to fix, although it might mean adding a separate invoke queue for config blocks in order to avoid breaking changes. Just waiting to hear if it's actually desirable or if the current behaviour should remain For a workaround without the patch, since the order does matter, then yes, if you need to ensure that the config blocks are run after all providers are registered with DI, you should register the config blocks at the very end. |
This change ensures that a module's config blocks are always invoked after all of its providers are registered. BREAKING CHANGE: Previously, config blocks would be able to control behaviour of provider registration, due to being invoked prior to provider registration. Now, provider registration always occurs prior to configuration for a given module, and therefore config blocks are not able to have any control over a providers registration. Example: Previously, the following: angular.module('foo', []) .provider('$rootProvider', function() { this.$get = function() { ... } }) .config(function($rootProvider) { $rootProvider.dependentMode = "B"; }) .provider('$dependentProvider', function($rootProvider) { if ($rootProvider.dependentMode === "A") { this.$get = function() { // Special mode! } } else { this.$get = function() { // something else } } }); would have "worked", meaning behaviour of the config block between the registration of "$rootProvider" and "$dependentProvider" would have actually accomplished something and changed the behaviour of the app. This is no longer possible within a single module. Fixes angular#7139
i still haven't heard whether or not it's desirable to let config blocks have a role in controlling the way providers are actually registered. But I'm not totally convinced that they should play such a role, so yeah |
This change ensures that a module's config blocks are always invoked after all of its providers are registered. BREAKING CHANGE: Previously, config blocks would be able to control behaviour of provider registration, due to being invoked prior to provider registration. Now, provider registration always occurs prior to configuration for a given module, and therefore config blocks are not able to have any control over a providers registration. Example: Previously, the following: angular.module('foo', []) .provider('$rootProvider', function() { this.$get = function() { ... } }) .config(function($rootProvider) { $rootProvider.dependentMode = "B"; }) .provider('$dependentProvider', function($rootProvider) { if ($rootProvider.dependentMode === "A") { this.$get = function() { // Special mode! } } else { this.$get = function() { // something else } } }); would have "worked", meaning behaviour of the config block between the registration of "$rootProvider" and "$dependentProvider" would have actually accomplished something and changed the behaviour of the app. This is no longer possible within a single module. Fixes angular#7139
Thanks @caitp Sorry about the fragmented questions I was moving from computer to laptop quite a bit and for some reason I kept missing messages. |
you could just defer execution of config blocks by making them async (step n) (so that the entire context can resolve BEFORE the config blocks execute), but then you would also need to make the initial compile n + 1 (timeout AFTER injector, which should be fine since timeouts are FIFO). |
also... how is |
@thebigredgeek |
7139 |
Goood |
This was discussed in IRC at around 1:30-2:00 PM pacific on 04/16/2014 with @caitp
Test case is here https://github.com/thebigredgeek/provider-test-case
Essentially, the config block throws an error, killing the tests. For some reason, however, no error is thrown when injecting the provider in the test using the module() method.
Any help or guidance here would be much appreciated. I am hoping I am simply missing something super obvious.
The text was updated successfully, but these errors were encountered: