4

Here is my code

for (var i=0; i<5; i++) {
    var url = generate_url(i) ;
    $http.get(url).then(function(response){
        var param2 = response.data.param2
        $scope.outputData.push({'index':i, 'param':param2}) ;
    }) ;
}

In this example, I suppose to obtain an array in the $scope.outputData with data similar to this:

[
  {'index':0,param:'a'},
  {'index':1,param:'b'},
  {'index':2,param:'c'},
  {'index':3,param:'d'},
  {'index':4,param:'e'},
]

but what i get is data like this:

[
  {'index':4,param:'a'},
  {'index':4,param:'b'},
  {'index':4,param:'c'},
  {'index':4,param:'d'},
  {'index':4,param:'e'},
]

In this case, the externel data that I mean is the variable i,

Please could you tell me the trouble ? and how do I proceed to attend my goal? Thank you in advance and sorry for my english :)

Paolo Moretti
  • 54,162
  • 23
  • 101
  • 92
user3172446
  • 59
  • 1
  • 7

2 Answers2

4

You can create a closure over the i variable to make sure it still has the value you want it to have when you use it.

for (var i=0; i<5; i++) {
    (function(counter) {
        var url = generate_url(i);
        $http.get(url).then(function(response){
            var param2 = response.data.param2
            $scope.outputData.push({'index':counter, 'param':param2}) ;
        });
    }(i));
}

But if the ordering of the resulting array matters, you will have to create a temporary array and then sort it on index.

You can use $q.all if you don't want to process any of the requests untill they have alle completed.

Something like this:

var promises = {};
for (var i=0; i<5; i++) {
    var url = generate_url(i) ;
    promises[i] = $http.get(url);
}
$q.all(promises).then(function(result) {
  for (index in result) {
      var param2 = result[index].data.param2
      $scope.outputData.push({'index':index, 'param':param2}) ;
  }
});

That should also preserve the ordering.

The docs for $q are here.

ivarni
  • 17,658
  • 17
  • 76
  • 92
1

This is a closure issue, the correct way to do it would be

for (var i=0; i<5; i++) {
   getData(i);
}
var getData=function(index) {
     var url = generate_url(index) ;
    $http.get(url).then(function(response){
        var param2 = response.data.param2
        $scope.outputData.push({'index':index, 'param':param2}) ;
    }) ;
}
Chandermani
  • 42,589
  • 12
  • 85
  • 88