2

I want to inject the same variables with different values multiples times to the same controller. This is what I tried. What is a way to get different values in each call?

HTML

<body ng-app="myApp">
    <div ng-controller="myCtrl" ng-init="test='helloworld';test1='helloworld2'">

    </div>
    <div ng-controller="myCtrl" ng-init="test='helloworld3';test1='helloworld4'">

    </div>
    <div ng-controller="myCtrl" ng-init="test='helloworld5';test1='helloworld6'">

    </div>
<body>

JavaScript code

var app = angular.module("myApp", []);

app.controller("myCtrl", ["$scope",function($scope) {
    console.log($scope.test);
    console.log($scope.test1);
}]);
Pankaj Parkar
  • 134,766
  • 23
  • 234
  • 299
Susheel Singh
  • 3,824
  • 5
  • 31
  • 66
  • You seem to ve rewriting the values of `test` and `test1` variables with different values (`helloworld, helloworld2, ...`). If you want them in the same controller, what should be the final values for these variables? – Roberto Linares Oct 22 '15 at 16:22
  • values are out of my hand. those are due to repeated `AEM` components. so its repeated multiple times – Susheel Singh Oct 22 '15 at 16:23
  • This could work for three different instances of the same controller, each with its own scope. Is that what you want? – Roberto Linares Oct 22 '15 at 16:29
  • yes i need that.@RobertoLinares I found a dirty fix though. Let me know a better way – Susheel Singh Oct 22 '15 at 16:32

3 Answers3

2

ng-init Docs says:

This directive can be abused to add unnecessary amounts of logic into your templates. There are only a few appropriate uses of ngInit, such as for aliasing special properties of ngRepeat, as seen in the demo below; and for injecting data via server side scripting. Besides these few cases, you should use controllers rather than ngInit to initialize values on a scope.

You shouldn't assign init values using ng-init. The correct way to do it would be to assign at the end on AngularJS controller function.

Technically, what happening is that the ng-init directive gets evaluated after the ng-controller function gets registered. That's why initialized values from the ng-init are not available inside the controller.

Basically, the reason behind ng-controller getting called first is the priority. If you look at the priority, the ng-init directive has 450 & the priority option of directive, where ng-controller directive has 500, while compiling the directive from the DOM AngularJS sorts them as per priorities. Thus ng-controller gets executed first.

Code

var app = angular.module("myApp", []);

app.controller("myCtrl", ["$scope",function($scope) {
    console.log(test);
    console.log(test1);

    // If you wanted to assign the values dynamically you could make Ajax here
    // that would call the server-side method which will return the values
    // and in success that Ajax you could set those scope values.
    // If any dependent function should get called after assigning them.
    // Then you can call that function from that Ajax success.
    $http.get('/getDefaultValues').then(function(response){
        var data = response.data;
        $scope.test= data.value1;
        $scope.test1 = data.value2;
    });
}]);

Edit

As it seems like above code wouldn't be possible to do because variable values are assigning from jsp/aspx page. For such reason I'd suggest another way of achieving this. I think that is more cleaner way of doing it.

I'd suggest you do initialize you angular app lazily by using angular.bootstrap rather than using ng-app which initialize app as soon as page loads.

angular.element(document).ready(function() {
  angular.bootstrap(document, ['TodoApp']);
});

Now you will think like how could it solve the problem of assigning the variable to the scope before making controller available, for that case you could create a value object and assign the variable which are populating on jsp/aspx page the value (kind of service)

<script type="text/javascript">
    angular.element(document).ready(function() {
      //like below you could get value inside your app by assigning
      //to some angular component like constant/value
      angular.module('TodoApp').value('sharedData', {
          'test': @myValueFromAspxPage,
          'test1': @myValueFromAspxPage1
      });
      angular.bootstrap(document, ['TodoApp']);
    });
</script>

By doing above thing you could easily make available your values inside a controller, & then no need to wait until one digest cycle to complete using $timeout. You could use this values inject inside sharedData value by injecting inside a controller.

Pankaj Parkar
  • 134,766
  • 23
  • 234
  • 299
  • `test='helloworld',test1='helloworld2` these values are dynamically generated and even the controller and added dynamically. so how do I pass it – Susheel Singh Oct 22 '15 at 16:14
  • controllers will be repeated if I do that. js is written seperately and components are added thrice which has this code.`
    `. nginit values are coming from `jsp`
    – Susheel Singh Oct 22 '15 at 16:19
  • 1
    @SusheelSingh how those values are comming on the page...I'd suggest to do an `$http` call from an controller & assign those value directly from angular controller itselft – Pankaj Parkar Oct 22 '15 at 16:22
  • I am not sure of that part. Need to dig that more. – Susheel Singh Oct 22 '15 at 16:23
  • @SusheelSingh could you look at my edit please..If you don't get what I'm saying..I can help you on that.. – Pankaj Parkar Oct 22 '15 at 16:44
  • 1
    I will get back to you once I trying your way. – Susheel Singh Oct 22 '15 at 16:45
  • 1
    @SusheelSingh surely.. Feel free to ask .. Happy coding :) – Pankaj Parkar Oct 22 '15 at 16:46
  • @SusheelSingh look at the updated answer..to more achieve it by using more cleaner way – Pankaj Parkar Oct 28 '15 at 19:28
  • so I need to run this script thrice because 3 components will be used with different values. script running thrice right ? – Susheel Singh Oct 29 '15 at 02:31
  • I can dynamically load all three values and they are same page. all three components. if it was on seperate page I would have instantiated from variables from server side values and use it in controller. But my case is different all the three values are on same page. w – Susheel Singh Oct 29 '15 at 08:39
  • @SusheelSingh then why don't the above solution will not work? – Pankaj Parkar Oct 29 '15 at 08:41
  • `'test': @myValueFromAspxPage, 'test1': @myValueFromAspxPage1` this value you want me to populate dynamcally right. if thats the case it will work for one component. I have two more components with same structure. so if I add one more component below the existing one new dynamic values will be set and first values will be replaced – Susheel Singh Oct 29 '15 at 08:47
  • 1
    sorry if you are not understanding my scenario its related to `adobe experience manager` a java cms.anyways I upvote your efforts – Susheel Singh Oct 29 '15 at 08:48
  • @SusheelSingh that might be possibility that you can't do that..Glad to help you..Thanks :) – Pankaj Parkar Oct 29 '15 at 19:04
0

Try this... As @tymeJV pointed out you need to use semicolons to separate the variable names in the HTML. You also need to use the $scope to reference the variables in the controller.

<body ng-app="myApp">     
    <div ng-controller="myCtrl" ng-init="test='helloworld';test1='helloworld2'">

    </div>
    <div ng-controller="myCtrl" ng-init="test='helloworld3';test1='helloworld4'">

    </div>
    <div ng-controller="myCtrl" ng-init="test='helloworld5';test1='helloworld6'">

    </div>
<body>

var app = angular.module("myApp", []);

app.controller("myCtrl", ["$scope",function($scope) {
    console.log($scope.test);
    console.log($scope.test1);
}]);
Eric
  • 6,563
  • 5
  • 42
  • 66
0

Found a dirty fix. Thanks all for your inputs.

Demo

var app = angular.module("myApp", []);

app.controller("myCtrl", ["$scope", '$timeout',function($scope, $timeout) {
    $timeout(function(){ 
        console.log($scope.test);
        console.log($scope.test1);  
    }, 1);
}]);
Pankaj Parkar
  • 134,766
  • 23
  • 234
  • 299
Susheel Singh
  • 3,824
  • 5
  • 31
  • 66
  • please dare to comment instead of down voting, thats the solution which works for me – Susheel Singh Oct 22 '15 at 16:31
  • You shouldn't do such a wrong thing.. `setTimeout` is not meant for such thing..using `ng-init` is wrong thing..you should get read of that first.. Read here https://docs.angularjs.org/api/ng/directive/ngInit .. – Pankaj Parkar Oct 22 '15 at 16:34
  • 1
    @PankajParkar: "wrong" is depending of situation. If you have a server side variables (ASP, PHP) to pass to your js controller is a right way to do it... – serge Oct 28 '15 at 18:20
  • @Serge Not very true..You have multiple other ways to do it..see it live here http://stackoverflow.com/a/33285651/2435473 – Pankaj Parkar Oct 28 '15 at 19:27