Ali-Alrabi
Ali-Alrabi

Reputation: 1698

Angularjs update scope inside iteration

In the following code i'm trying to get subquestions list for each question and show them in the view ,but i have problem in updating subquestion for each question,it don't update so I get same subquestion list for all question.

How can I show each question and list all subquestion under it?

  function loadAllQuestionGroup () {
    Questiongroup.query({}).$promise.then(function(group){
        vm.questiongroups = group;
        for(var i=0;i<group.length;i++){
           var grouptitle=group[i].title
            Question.questionsByQuestionGroup({id:group[i].id}).$promise.then(function(question){
                vm.question = question; 
               for(var j=0;j<question.length;j++){    
                  Subquestion.subquestionsByQuestion({id:question[j].id}).$promise.then(function(subquestion){
                      vm.subquestions=subquestion;
                    });                        
              }
         });
        }
      });
    }

 <div ng-repeat="question in vm.question">
   {{question.name}}
   <div ng-repeat="subquestion in vm.subquestions">
     {{subquestion.name}}
   </div>
 </div>

Upvotes: 0

Views: 81

Answers (2)

georgeawg
georgeawg

Reputation: 48968

Individual questions need to be pushed to a question list. Create a subquestion list for each individual question. Individual subquestions need to be pushed to their respective lists.

function loadAllQuestionGroup () {
    Questiongroup.query({}).$promise.then(function(group){
        vm.questiongroups = group;
        //Initialize question list
        vm.questionList = [];
        for (var i=0;i<group.length;i++){
            var grouptitle=group[i].title;
            Question
              .questionsByQuestionGroup({id:group[i].id})
              .$promise
              .then(function(question){
                //Push question to list
                vm.questionList.push(question); 
                for (var j=0;j<question.length;j++) {
                    //Initialize subquestion list
                    question.subquestionList = [];
                    Subquestion
                        .subquestionsByQuestion({id:question[j].id})
                        .$promise
                        .then(function(subquestion){
                             //Push subquestion to list
                             question.subquestionList.push(subquestion);
                        })
                   ;                        
                };
              })
            ;
        }
    });
}

Subquestion interation (ng-repeat) should be done on the question iterator.

<div ng-repeat="question in vm.questionList">
   {{question.name}}
   <div ng-repeat="subquestion in question.subquestionList">
     {{subquestion.name}}
   </div>
</div>

Notice that a subquestionList property was added to each question in the questionList.

Upvotes: 1

Luger
Luger

Reputation: 2120

Looks like it's not an issue related with angular scope, it's pure javascript scope that you have trouble with. If you making asynchronous calls in the loop, you will receive each time the last element. To fix it, you should wrap promises inside loop with anonymous functions.

Check this classic example(you can think that setTimeout function is equivalent of your Question.questionsByQuestionGroup({id:group[i].id}).$promise, they are both async functions)

//THIS IS EQUIVALENT TO YOUR CASE
//In this case it will return each time last element, 5 in this case
for (var i = 0; i < 5; i++) {
  setTimeout(function() {
    console.log(i)
  });
}
//Result: 5 5 5 5 5

//THIS IS HOW YOU SHOULD REFACTOR
//Make a wrapper for async, and it will work as needed
for (var j = 0; j < 5; j++) {
  (function(index) {
    setTimeout(function() {
      console.log(index)
    });
  })(j);
}
//Result: 0 1 2 3 4

P.S. After you will fix it with wrappers, your code will be even more unreadable, better to refactor it to separate functions.

Upvotes: 1

Related Questions