1

Angular partial - HTML. BaseCtrl

 <div ng-controller="SelectTagCtrl">       
     <input type="text" ng-init="setTags(viewData['users'])" ui-select2="tagAllOptions" ng-model="tagsSelection" name="users"  />   
     {{viewData['users']}} ECHOES CORRECTLY. 
     But undefined when passed inside ng-init callback.
 </div>

 <input type="text" class="span12" placeholder="Brief Description" name="description" value="{{viewData['description']}}">
 ECHOES CORRECTLY.     

Controller.js

function SelectTagCtrl(){
 $scope.setTags = function(data){       
    // data is undfined when viewData['users'] is used. <-- PROBLEM
    // correct when I pass some static string. 
 }     
}


//POPULATING viewData to be used inside view partial.  

function BaseCtrl(){
    $http.get(url).success(function(data){   
    $scope.viewData = data.data || [];        
    $scope.view_type = $scope.viewData['view_type'];
    $scope.fields = data.data.fields;                   
    console.log($scope);

  }).error();
}
6
  • 2
    It is most likely because the $http.get has not completed by the time the ng-init directive is compiled. Commented May 15, 2013 at 20:10
  • That depends what are you trying to do exactly in setTags? Off the cusp I'd say move your logic inside of setTags into your success callback and don't use ng-init at all. Commented May 15, 2013 at 20:16
  • I tried that. as it seemed obvious. but that affects other things. Commented May 15, 2013 at 20:18
  • 1
    What is it that you would like to achieve? I don't think this is the intended use for ng-init it is meant to initialize values before the application is bootstrapped. I'm not sure it is possible to use it with asynchronous calls. It could be possible with perhaps some elaborate use of $q. Commented May 15, 2013 at 20:25
  • It would work thought not correctly. If I put the logic of setTags inside success callback. but problem there is if I update the ng-model value the old value is getting lost. I will update the question with my scenario Commented May 15, 2013 at 20:31

2 Answers 2

3

Using timeout would be a workaround, instead I would take a $scope variable inside the controller to know if the ajax call has completed.

The problem is ng-init might get called before ajax completion.

I already had ui-if directive configured in my angular project, so I used it with the combination of $scope variable to get the things working.

<div ng-controller="SelectTagCtrl" ui-if="ajax_done">       
     <input type="text" ng-init="setTags(viewData['users'])" ui-select2="tagAllOptions" ng-model="tagsSelection" name="users"  />  
</div>

And inside controller,

 $http.get(gurl + '.json').success(function(data,status){
      // some stuff
      $scope.ajax_done = true;
 }).error();

Because of angular's magical two-way binding, the element will get updated. Now it sees that ajax request is completed, ui-if will get a truthy value and ng-init directive of the element will get a chance to execute its callback.

EDIT: ui-if was removed from Angular UI in favour of ng-if which is now built in.

Sign up to request clarification or add additional context in comments.

Comments

2

Here are two different changes to your fiddle that appear to work.

Fiddle 1 - this version uses $scope.$apply(exp) as described in the documentation here and is useful when you are modifying angular bound data outside of the angular framework. In this example setTimeout is the culprit.

setTimeout(function(){
    console.log("updateVal" );

    $scope.$apply(function() {
        $scope.updateVal2();
    });
    console.log($scope.tagsSelection);
},5000);

Fiddle 2 - this version uses angular's wrapper for setTimeout called the $timeout service.

$timeout(function(){
    console.log("updateVal" );

    $scope.updateVal2();
    console.log($scope.tagsSelection);
},5000);

2 Comments

Found your answer useful. +1, but setTimeOut is not the correct way to solve this. I will post how I solved my specific problem
Yeah it definitely felt like I wasn't necessarily answering the question per se but glad it helped!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.