I have a for cycle that iterates over an associative array. foreach entry i have to make an ajax request and fill another array with retrieved data.
The problem is that the success callback is asynchronous so it runs only after the cycle has been iterated. this means that my data array is filled with multiple copies of the last ajax request result.
This is my code (simplified):
var channels = {
"misured": "channel_misured",
"plan": "channel_plan"
};
var data; //Initial data is empty
function getData() {
data = new Array();
for (var seriesData in channels) {
var currentData = new Array();
$.ajax({
type: "GET",
url: 'http://' + serverAddress + ':' + serverPort + '/GetChannelBufferAsJsonp?channelName=' + channels[seriesData] + '&callback=?',
dataType: "json",
async: false,
success: function (json) {
var time = new Date().getTime() + 3600000;
for (var i = 0; i < json.length; i++) {
currentData.push({
x: time + i * 30000,
y: json[i]
});
}
data.push({
id: seriesData,
name: "Production " + seriesData,
data: currentData
});
}, error: function () {
console.log("error", this);
}
});
}
}
So data has 2 elements (correct) but both of them comes from “plan_channel” (that is my data source).
I know this is a classic, well know “problem” (or feature) of ajax requests but i cannot see how i can get rid of it.
Can you tell how to wait for the success callback to end before going to the next iteration?
This is the only way (off the top of my head) I can see to refactor your code. Its a bit pointless though. You’ve got your set up all wrong IMO, you shouldn’t be doing it that way. The best way I can see to do it would be to send the whole array in one ajax request to the ajax script, deal with it all in the php (or whatever) and spit it back out in the format you want it in the javascript. Otherwise you’d be better off finding a better way to do this. For instance instead of having a for loop you could have an ajax request which calls back to the
getData()function in the success call.This is how I would rewrite the code above:
In order to do this you might have to count the times you go through the function or something in order to be able to pass the next channel into the function again.