0

Possible Duplicate:
Passing functions to setTimeout in a loop: always the last value?

I know I need to use closure to deal with problem, but I'm not sure how; I have function, where I get data from server:

function loadGraph(chartDataStreams) { //length of chartDataStreams is two

  initCharts(); //init charts area
  for (c in chartDataStreams) {
    var chartData = [];
    alert(c); // says : 0, then 1
    getDataFromServer(chartDataStreams[c].x, chartDataStreams[c].y,function (data) {
       for (d in data.datapoints) {
         var item = { date: new Date(data.datapoints[d].at), value:data.datapoints[d].value };
         chartData.push(item);
        }
      alert(c); // says: 1 then 1
      updateGraphData(chartData); 

    });
  }
}

in this function I need to call updateGraphData, which updates graph data provider with chartData. Problem is that in chartData I don't have just the actual data but also the data from previous loop cycle. I think this the right place to use closures, but I'm not sure how.. Do you have any ideas?

//edit: I put the declaration of chartData by mistake outside the getDataFromServer function, but I've got still one problem: check the edited code. From the second alert I want to say 0 and 1, not just 1,1

Community
  • 1
  • 1
user1762087
  • 440
  • 5
  • 16
  • Is there a reason your declaring `chartData` twice? Also, can you describe what is not working, or what are the actual results vs expected results? – Ben Felda Jan 29 '13 at 16:53
  • and better to see `updateGraphData` implementation too. and try to empty charData before loop just write chartData = []; inside anonymous function and delete second declaration – Vadim Ivanov Jan 29 '13 at 16:57
  • also, http://stackoverflow.com/questions/2520587/variable-in-javascript-callback-functions-always-gets-last-value-in-loop and http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example?rq=1 –  Jan 29 '13 at 17:00
  • gosh, I was idiot :-D I copy pasted my previosly written code badly and I declared it outside function by mistake – user1762087 Jan 29 '13 at 18:06
  • But still the problem with same value of variable.. I've edited the original quesiton – user1762087 Jan 29 '13 at 18:31

1 Answers1

1

Instantiate the chartData in the callback instead of outside.

function loadGraph(chartDataStreams) {
    initCharts();
    for (c in chartDataStreams) {
        getDataFromServer(chartDataStreams[c].x, chartDataStreams[c].y, function (data) {

            var chartData = []; // RIGHT HERE

            for (d in data.datapoints) {
                var item = {
                    date: new Date(data.datapoints[d].at),
                    value: data.datapoints[d].value
                };
                chartData.push(item);
            }
            updateGraphData(chartData);
        });
    }
 }

This way each callback gets its own fresh chartData array when invoked.

Blocks do not create variable scope in JavaScript, only functions, so the outer chartData was scoped to the outer function, and was overwritten with each loop iteration.

Its last overwrite was what all the callbacks used when they were finally called, so all the data ended up in that shared array.

the system
  • 9,244
  • 40
  • 46