I'm attempting to loop through an ajax call for 3 different json files with the same naming convention and structure (but with slightly different data). I have been using deferred objects instead of the success option ever since I read a response by Alnitak in the forum (jQuery ajax success callback function definition) so that my ajax handling and callback handling could be decoupled. Below is my code:
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=ISO-8859-1" />
<title>Stuff</title>
<script src="jquery-1.9.1.min.js" type="text/javascript"></script>
</head>
<body>
<script Language="JavaScript">
var myData = [];
var myURL = ["ticker1.json","ticker2.json","ticker3.json"]; //New Array for my URLs
function getData(m) {
return $.ajax({
url : myURL[m], //<<<---Want to loop through this array
type : 'GET',
dataType: 'json'
});
}
function handleData(data){
for (var i=0; i<data.test.msgOne.length; i++){
myData[i] = data.test.msgOne[i];
}
};
for (var j=0; j<3; j++){
console.log(j); //<<---First console statement
var ajaxCall = getData(j).done(handleData);
$.when(ajaxCall).done(function(){ //wait until the ajax call is done before writing
console.log(j); //<<---Second console statement
for (var k=0; k<3; k++){
document.write(myData[k])
document.write('<br><br>');
}
});
}
</script>
</body>
</html>
My code consists of an function called getData which performs an ajax call, then a function called handleData which simply loops through data in the json file from the ajax call and stores the data in an array myData. Then a for-loop attempts to output the data for the array myData to the screen. However, the problem is I am only getting the data from the first json file output on the screen, instead of all three sequentially.
So what I did was input two console.log statements in the for-loop: one before the ajax call and one after the ajax call gets done. The first console.log outputs 0,1,2 sequentially as expected, and the second gives a 3, which is unexpected. So then I assumed that the ajax calls weren't returning before the counter finishes. I replaced the for-loop with some logic statements and a while-loop (yes, I know the dangers of code running indefinitely) given below:
var j=0;
var whileFlag= new Boolean(1);
var ajaxFlag = new Boolean(1);
while (whileFlag) {
if (ajaxFlag > 0) {
ajaxFlag = 0;
console.log(j);
var ajaxCall = getData(j).done(handleData);
}
$.when(ajaxCall).done(function(){
console.log(j);
for (var k=0; k<3; k++){
document.write(myData[k])
document.write('<br><br>');
}
ajaxFlag = 1;
j++;
});
if (j>=3) {whileFlag = 0};
}
The replacement code was an attempt to force the ajax calls to finish and then execute code before moving onto the next ajax call. Well, the end result was a frozen browser, which was no bueno. Does anyone know how I might be able to go about writing the myData array for each of my json files to the screen? Any help and constructive comments are appreciated. Also, I need to keep the ajax call asynchronous since I will be working with jsonp datatypes in the future.
Additional question: I believe the browser hang up is due to ajax not returning the call, but the questions is why? If I choose not to implement the for-loop in the first example, and instead just set the j variable explicitly to 0, or 1, or 2, the data prints-out fine for the chosen json file, but If I do more than that it will only print the set of data from the first json file. It's like it's not possible to do multiple ajax calls or something. Any insight and help is appreciated. Thanks.
The problem is your while loop is equivalent to...
while (whileFlag) {
if (ajaxFlag > 0) {
ajaxFlag = 0;
console.log(j);
var ajaxCall = getData(j).done(handleData);
}
// Some thrid party (asynch Handler) changes j
if (j>=3) {whileFlag = 0};
}
so ideally till Ajax completes your code runs as
while (whileFlag) {
if (j>=3) {whileFlag = 0};
}
which hangs your browser...
If you want to really wait for 2nd Ajax call till 1st completes and so on..
function getData(m) {
return $.ajax({
url : myURL[m], //<<<---Want to loop through this array
type : 'GET',
dataType: 'json',
myJ: m
});
}
function handleData(data){
for (var i=0; i<data.test.msgOne.length; i++){
myData[i] = data.test.msgOne[i];
}
for (var k=0; k<3; k++){
document.write(myData[k])
document.write('<br><br>');
}
if(this.myJ<2){
var myJ=this.myJ;
setTimeout(function(){
getData((myJ+1)).done(handleData).fail(failed);
}, 100);
}
};
getData(0).done(handleData);
function failed(jqXHR, textStatus, errorThrown){
alert("textStatus="+textStatus);
alert("Error= "+errorThrown);
}
As per comment with alert if its working then use settimeout.. and it will work
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With