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

144 views Asked by At

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>

1

There are 1 answers

1
pidizzle On BEST ANSWER

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.