简体   繁体   中英

Angular $scope.variable undefined

I am having a problem that my $scope.todo list always returns a undefined when using the angular function ng-repeat. If I define the $scope.todo it works perfectly but when I use the solution below to fetch results and add it to the variable I get an undefined before it seems to have a chance to go and retrieve the correct values

I have now added a bit better code to explain my problem. After looking at some of the jsfiddles below and trying those solutions I'm starting to think its something to do with my callbacks.

function TodoCtrl($scope) {

   $scope.todos = [];

   buildInitialList(function (result){
       console.log(result); //Logs defined after the undefined below
       $scope.todos = result;
   });

   console.log($scope.todos); //Logs undefined before the defined log above
}

function buildInitialList(callback){
    //Simulates call to db
    setTimeout(function (){
    callback([{text: 'item 1', done: false},
        {text: 'item 2', done: false}]);
},2000);
}

function fetch(url, callback) {
    $.getJSON(url, function (data, status) {
        callback(data);
    });
}

Shouldn't this:

$scope.testList = buildInitialList(function (result){
     return result;
   }

Be like this:

$scope.testList = buildInitialList( function (result){return result;} );

And buildInitialList function is not returning any value. Based on your sample code it could something like this:

function buildInitialList(callback){
   var result = doWorkAndGetResult();
   callback(result);
  //missing return value...
   return result; /*maybe?*/
}

Here is a fully working jsfiddle demo:

http://jsfiddle.net/f9ee4/1/

You are never actually assigning your result to the scope variable. Your callback is being called, but the return value of your callback is NOT what gets assigned to your scope property.

By using a callback, I'm assuming you have some sort of async call in that global function. If you don't have an async call in there, then you should just return the value from buildInitialList, without using a callback.

Here's a fiddle that works: http://jsfiddle.net/973nW/

function MyCtrl($scope) {
    buildInitialList(function (result){
        $scope.name = result;
    });  
}

Side note: using a global function isn't a good idea, you may want to consider putting your function into a service.

After pulling my hair out and thinking something was wrong with my javascript it turns out the problem was actually within the ng-repeat I was using in the HTML

This is what my html looked like

<ul class="unstyled">
        <li ng-repeat="todo in todos">
            <input type="checkbox" ng-model="todo.done">
            <span class="done-{{todo.done}}">{{todo.text}}</span>
        </li>
</ul>

This worked fine when I had defined a list of ToDo's right from the start however when I had to go to the DB & retrieve that list the results never seemed to be applied to the original $scope.todos

I had to use the $scope.$apply function to make sure when my values were retrieved from the DB they were actually applied to the $scope afterwards

buildInitialList(function (result){
    $scope.$apply(function (){
        console.log(result);
        $scope.todos = result;
    });
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM