angularjsangularjs-scopeangularjs-controlleras

AngularJS 1 injecting $scope inline in one controller breaks second controller


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>


Solution

  • 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.