I am trying to improve on the W3Cschools "get something output" syntax for coding AngularJS controllers by following the community driven style guide on Github
As advised, I want to
Avoid use of $scope service to define functions and properties as part of controllers.
by injecting $scope.
I have found that, while the first controller returns its properties as planned, a second controller in the application is just broken: even a using $scope
implementation returns AngularJS markup like Angular is switched off.
I made a simple mock-up, leaving controller as
syntax in the view and adjusted the using $scope
implementation to define an object variable to assign to $scope so that the syntax of the expression did not have to change in the view.
As initially posted, the injection of $scope
implementations of the two controllers are commented out - and both controllers work.
If you comment out the using $scope
implementation for the 1st controller [and uncomment its injection of $scope
version] the desired text:-
String property [Example1CtrlOutput] of controller Example1Ctrl [returned instead of using $scope]
is shown for the 1st controller but the 2nd one just shows the un-modified AngularJS expression markup:-
{{e2.Example2CtrlOutput}}
Can anybody say what is going wrong?
var app = angular.module( "myApp", [] ) ;
// --- implementation using $scope to define property of controller "Example1Ctrl"
app.controller("Example1Ctrl", [ '$scope' ,
function($scope) {
var obj = { Example1CtrlOutput : "String property of object inside controller Example1Ctrl" } ;
$scope.e1 = obj ;
}]);
// ---------------------------------------------------------------------------------
// --- implementation of controller "Example1Ctrl" injecting $scope ---------------
/*
app.controller("Example1Ctrl", Example1Ctrl ) ;
Example1Ctrl.$inject[ '$scope' ] ;
function Example1Ctrl($scope) {
var e1 = this ; // avoids overuse of "this"
e1.Example1CtrlOutput = "String property [Example1CtrlOutput] of controller Example1Ctrl [returned instead of using $scope]" ;
}
*/ // ---------------------------------------------------------------------------------
// --- implementation using $scope to define property of controller "Example2Ctrl"
app.controller("Example2Ctrl", [ '$scope' ,
function($scope) {
var obj = { Example2CtrlOutput : "String property of object inside controller Example2Ctrl" } ;
$scope.e2 = obj ;
}]);
// ---------------------------------------------------------------------------------
/*
// --- implementation of controller "Example2Ctrl" injecting $scope ---------------
app.controller("Example2Ctrl", Example2Ctrl ) ;
Example2Ctrl.$inject[ '$scope' ] ;
function Example2Ctrl($scope) {
var e2 = this ; // avoids overuse of "this"
e2.Example2CtrlOutput = "String property [Example2CtrlOutput] of controller Example2Ctrl [returned instead of using $scope]" ;
}
// ---------------------------------------------------------------------------------
*/
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="Example1Ctrl as e1">
{{e1.Example1CtrlOutput}}
</div>
<div ng-controller="Example2Ctrl as e2">
{{e2.Example2CtrlOutput}}
</div>
</div>
I have found a solution to your problem. You must move app.controller
for Example2Ctrl underneath the app.controller
for Example1Ctrl.
So that your code looks like
app.controller("Example1Ctrl", Example1Ctrl );
app.controller("Example2Ctrl", Example2Ctrl );
Edit:
So the actual problem was the $inject
part. $inject
never exists as a property on the controller. You are supposed to set $inject
to an array of the services, directives, etc.
I.E Example1Ctrl.$inject = ['$scope']
.
The reason moving the app.controller
fixed the output was because angular was able to register the controller before hitting the error.
You will also want to move the Example1Ctrl.$inject
and Example2Ctrl.$inject
before the controllers are registered, or the $scope
will be undefined and result in an error.
Source: https://docs.angularjs.org/api/auto/service/$injector.