2

I'm trying to create many charts each with different JSON data. I have a loop which tries to load the data for each chart, but although the calls are asynchronous, the loop index is always the last one. Instead of doing 0,1,2,3,4,5 it does 5,5,5,5,5,5. Here's an example with 2 items to loop over:

var charts_data = [ [some_url, "value1", "value2", 1],
                    [some_url, "value1", "value2", 1] ]

for (var i = 0; i < charts_data.length; i++) {

    var _this = this;
    var _i = i

    d3.json(charts_data[i][0], function(error, json_data) {
        console.log("- - - - - - - - - - - - - - - - - - #"+ _i +" ORIGINAL DATA : ")
        format_raw_data(json_data, _this.charts_data[_i][1], _this.charts_data[_i][2], _this.charts_data[_i][3]); 
    });

}

And the problem is shown by the console log which says:

- - - - - - - - - - - - - - - - - - #1 ORIGINAL DATA :  
- - - - - - - - - - - - - - - - - - #1 ORIGINAL DATA :  

I tought that d3.json being asynchrnous meant this wouldn't happen, but I guess I don't fully grasp that concept.

Any ideas for a remedy?

Anto Jurković
  • 11,188
  • 2
  • 29
  • 42
jcnesci
  • 91
  • 2
  • 10

1 Answers1

2

The problem is that the variable _i is still bound to the outside scope and is updated before the async call to fetch the json data is made.

It can be fixed by wrapping it in a closure like this:

for (var i = 0; i < charts_data.length; i++) {

    var _this = this;
    (function (_i) {

        d3.json(charts_data[i][0], function(error, json_data) {
            console.log("- - - - - - - - - - - - - - - - - - #"+ _i +" ORIGINAL DATA : ")
            format_raw_data(json_data, _this.charts_data[_i][1], _this.charts_data[_i][2], _this.charts_data[_i][3]); 
        });
    })(i);
}
musically_ut
  • 34,028
  • 8
  • 94
  • 106
  • Awesome, thanks so much. I had searched tons already but also just found a similar answer here, if useful for others: http://stackoverflow.com/questions/13343340/calling-an-asynchronous-function-within-a-for-loop-in-javascript – jcnesci Nov 21 '13 at 20:59