Skip to content

Commit 3454e80

Browse files
committed
feat($controller): throw error when requested controller is not registered
Previously, it would throw the ng:areq error, which is less specific and just informs that the requested controller did not yield a function. Given how commonly controllers are used in Angular, it makes sense to have a specific error. The ng:areq error is still thrown when the registered controller is not a function. Closes angular#14980
1 parent 859348c commit 3454e80

File tree

5 files changed

+46
-2
lines changed

5 files changed

+46
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
@ngdoc error
2+
@name $controller:ctrlreg
3+
@fullName A controller with this name is not registered.
4+
@description
5+
6+
This error occurs when the {@link ng.$controller `$controller()`} service is called
7+
with a string that does not match any of the registered controllers. The controller service may have
8+
been invoked directly, or indirectly through the {@link ng.ngController `ngController`} directive,
9+
or when inside a {@link angular.Module#component component} / {@link angular.Module#directive directive}
10+
definition (when using string notation for the controller property).
11+
12+
Sources for this error can be:
13+
14+
1. You have a typo in the {@link ng.ngController `ngController`} directive,
15+
in a {@link angular.Module#component component} / {@link angular.Module#directive directive}
16+
definition's controller property, or in the call to {@link ng.$controller `$controller()`}.
17+
2. You have not registered the controller (neither via {@link angular.Module#controller `Module.controller`}
18+
nor {@link ng.$controllerProvider#register `$controllerProvider.register()`}.
19+
3. You have a typo in the *registered* controller name.
20+
4. You want to use controllers defined on the `window`, but have turned off
21+
{@link ng.$controllerProvider#allowGlobals `allowGlobals()`}.
22+
23+
24+
Please consult the {@link ng.$controller $controller} service api docs to learn more.

docs/content/error/ng/areq.ngdoc

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@
55

66
AngularJS often asserts that certain values will be present and truthy using a
77
helper function. If the assertion fails, this error is thrown. To fix this problem,
8-
make sure that the value the assertion expects is defined and truthy.
8+
make sure that the value the assertion expects is defined and matches the type mentioned in the
9+
error.

src/ng/controller.js

+5
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,11 @@ function $ControllerProvider() {
122122
: getter(locals.$scope, constructor, true) ||
123123
(globals ? getter($window, constructor, true) : undefined);
124124

125+
if (!expression) {
126+
throw $controllerMinErr('ctrlreg',
127+
'The controller with the name \'{0}\' is not registered.', constructor);
128+
}
129+
125130
assertArgFn(expression, constructor, true);
126131
}
127132

test/ng/controllerSpec.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,12 @@ describe('$controller', function() {
161161
}).toThrow();
162162
}));
163163

164+
it('should throw ctrlreg when the controller name does not match a registered controller', inject(function($compile, $rootScope) {
165+
expect(function() {
166+
$controller('IDoNotExist', {$scope: {}});
167+
}).toThrowMinErr('$controller', 'ctrlreg', 'The controller with the name \'IDoNotExist\' is not registered.');
168+
}));
169+
164170

165171
describe('ctrl as syntax', function() {
166172

@@ -227,7 +233,6 @@ describe('$controller', function() {
227233
'Must match `__name__ as __id__` or `__name__`.');
228234
});
229235

230-
231236
it('should allow identifiers containing `$`', function() {
232237
var scope = {};
233238

test/ng/directive/ngControllerSpec.js

+9
Original file line numberDiff line numberDiff line change
@@ -150,4 +150,13 @@ describe('ngController', function() {
150150
$httpBackend.flush();
151151
expect(controllerScope.name).toBeUndefined();
152152
}));
153+
154+
it('should throw ctrlreg when the controller name does not match a registered controller', inject(function($compile, $rootScope) {
155+
element = jqLite('<div ng-controller="IDoNotExist"></div>');
156+
157+
expect(function() {
158+
element = $compile(element)($rootScope);
159+
}).toThrowMinErr('$controller', 'ctrlreg', 'The controller with the name \'IDoNotExist\' is not registered.');
160+
}));
161+
153162
});

0 commit comments

Comments
 (0)