Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 7a1750a

Browse files
author
robertmirro
committedApr 8, 2016
fix(loader): module.decorator order of operations is now irrelevant
`module.decorator` is now processed via the configBlocks order of operations and: 1. no longer throws if declared before the provider being decorated 2. guarantees the correct provider will be decorated when multiple, same-name providers are defined (1) Prior to this fix, declaring `module.decorator` before the provider that it decorates results in throwing an error: ```js angular .module('theApp', []) .decorator('theFactory', theDecoratorFn) .factory('theFactory', theFactoryFn); // Error: [$injector:modulerr] Failed to instantiate module theApp due to: // Error: [$injector:unpr] Unknown provider: theFactoryProvider ``` The result of this fix now allows for the declaration order above. (2) Prior to this fix, declaring `module.decorator` before the final, same-named provider results in that provider **not** being decorated as expected: **NOTE:** Angular does not use provider name spacing, so the final declared provider is selected if multiple, same-named providers are declared. ```js angular .module('theApp', []) .factory('theFactory', theFactoryFn) .decorator('theFactory', theDecoratorFn) .factory('theFactory', theOtherFactoryFn); // `theOtherFactoryFn` is selected as 'theFactory' provider but it is **not** decorated // via `theDecoratorFn` as expected ``` The result of this fix ensures that `theOtherFactoryFn` will be decorated as expected when using the declaration order above. BREAKING CHANGE: `module.decorator` declarations are now processed as part of the `module.config` queue and may result in providers being decorated in a different order if `module.config` blocks are also used to decorate providers via `$provide.decorator`. For example, consider the following declaration order in which 'theFactory' is decorated by both a `module.decorator` and a `$provide.decorator`: ```js angular .module('theApp', []) .factory('theFactory', theFactoryFn) .config(function($provide) { $provide.decorator('theFactory', anotherDecoratorFn); }) .decorator('theFactory', theDecoratorFn); ``` Prior to this fix, 'theFactory' provider would be decorated in the following order: 1. theDecoratorFn 2. anotherDecoratorFn The result of this fix changes the order in which 'theFactory' is decorated because now `module.decorator` declarations are processed in the same order as `module.config` declarations: 1. anotherDecoratorFn 2. theDecoratorFn Closes #12382
1 parent 1964620 commit 7a1750a

File tree

2 files changed

+5
-4
lines changed

2 files changed

+5
-4
lines changed
 

‎src/loader.js

+4-3
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ function setupModuleLoader(window) {
203203
* @description
204204
* See {@link auto.$provide#decorator $provide.decorator()}.
205205
*/
206-
decorator: invokeLaterAndSetModuleName('$provide', 'decorator'),
206+
decorator: invokeLaterAndSetModuleName('$provide', 'decorator', configBlocks),
207207

208208
/**
209209
* @ngdoc method
@@ -349,10 +349,11 @@ function setupModuleLoader(window) {
349349
* @param {string} method
350350
* @returns {angular.Module}
351351
*/
352-
function invokeLaterAndSetModuleName(provider, method) {
352+
function invokeLaterAndSetModuleName(provider, method, queue) {
353+
if (!queue) queue = invokeQueue;
353354
return function(recipeName, factoryFunction) {
354355
if (factoryFunction && isFunction(factoryFunction)) factoryFunction.$$moduleName = name;
355-
invokeQueue.push([provider, method, arguments]);
356+
queue.push([provider, method, arguments]);
356357
return moduleInstance;
357358
};
358359
}

‎test/loaderSpec.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ describe('module loader', function() {
4848
expect(myModule.requires).toEqual(['other']);
4949
expect(myModule._invokeQueue).toEqual([
5050
['$provide', 'constant', jasmine.objectContaining(['abc', 123])],
51-
['$provide', 'decorator', jasmine.objectContaining(['dk', 'dv'])],
5251
['$provide', 'provider', jasmine.objectContaining(['sk', 'sv'])],
5352
['$provide', 'factory', jasmine.objectContaining(['fk', 'fv'])],
5453
['$provide', 'service', jasmine.objectContaining(['a', 'aa'])],
@@ -60,6 +59,7 @@ describe('module loader', function() {
6059
]);
6160
expect(myModule._configBlocks).toEqual([
6261
['$injector', 'invoke', jasmine.objectContaining(['config'])],
62+
['$provide', 'decorator', jasmine.objectContaining(['dk', 'dv'])],
6363
['$injector', 'invoke', jasmine.objectContaining(['init2'])]
6464
]);
6565
expect(myModule._runBlocks).toEqual(['runBlock']);

0 commit comments

Comments
 (0)
This repository has been archived.