Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Looping through an ajax callback with jquery

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.

like image 415
ADT Avatar asked May 16 '13 16:05

ADT


Video Answer


1 Answers

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

like image 165
rahul maindargi Avatar answered Sep 20 '22 01:09

rahul maindargi