0

Say for example I have the following code:

for(var i=0; i < itemlist.length; i++){
    var item = itemlist[i];
    var id = item.id;
    $http.get(id + '.json').success(function(data){
        //do something with data.
        console.log(item.name);
    }
}

The name displayed in the console will be a repeated value (I think the first value in the array itemlist), i.e. the callback function doesn't know about the variable item.

With my level of understanding this is strange. Is there a way to pass in additional variables to this callback function - and/or - could someone enlighten me on why the scope of this variable behaves in this way?

Tito
  • 832
  • 10
  • 24
  • it should be closed on that just fine. – Daniel A. White Mar 04 '14 at 00:31
  • [Creating closures in loops: A common mistake](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures#Creating_closures_in_loops.3A_A_common_mistake) & http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example – Arun P Johny Mar 04 '14 at 00:32

2 Answers2

2

Assuming itemlist is an array, you can use angular.forEach() like

angular.forEach‎ (itemlist, function (item, i) {
    var id = item.id;
    $http.get(id + '.json').success(function (data) {
        //do something with data.
        console.log(item.name);
    })
})

The problem as I pointed out in the comment is wrong use of closure variable in a loop.

If you wants to support only IE9+ then, you can even use Array.forEach() like

itemlist.forEach‎ (function (item, i) {
    var id = item.id;
    $http.get(id + '.json').success(function (data) {
        //do something with data.
        console.log(item.name);
    })
})
Arun P Johny
  • 384,651
  • 66
  • 527
  • 531
  • ...or maybe `itemlist.forEach(function(item, i) {...});` [is supported well enough](http://kangax.github.io/es5-compat-table/#Array.prototype.forEach)? – Jan Turoň Mar 04 '14 at 00:44
  • @JanTuroň yes... in my current project I need to support IE8+ so I always ends up using those library functions.... – Arun P Johny Mar 04 '14 at 00:49
0

to associate a value with a callback function you should make use of bind. This way you can attach any object to callback and access it via this.object:

function yourFunction() {
    for(var i=0; i < itemlist.length; i++){
    var item = itemlist[i];
    var id = item.id;
    var onSuccess = onSuccess.bind({item: item});
    $http.get(id + '.json').success(onSuccess);

}

 function onSuccess(data) {
    console.log(this.item.name);
}
TechMaze
  • 477
  • 2
  • 9