ToX 82
ToX 82

Reputation: 1074

When all ajax requests are done, then

I need to do a bunch of ajax requests (I need to do this to populate some select boxes) and, after everything is loaded, hide the loading panel.

This works perfectly if I do this:

$.when(
    $.getJSON(applicationUrl + "data/codiciPaese.json", function (json) {
        data.codiciPaese = json;
        $.each(data.codiciPaese, function (index, item) {
            $(".codiciPaese").append($('<option>', {
                value: item.code,
                text: item.code + " - " + item.name
            }));
        });
    }),
    $.getJSON(applicationUrl + "data/regimiFiscali.json", function (json) {
        data.regimiFiscali = json;
        $.each(data.regimiFiscali, function (index, item) {
            $(".regimiFiscali").append($('<option>', {
                value: item.code,
                text: item.code + " - " + item.name
            }));
        });
    }),
    $.Deferred(function (deferred) {
        $(deferred.resolve);
    })
).done(function () {
    $('#loading').fadeOut(800, function () {
        // something else
    });
});

But, since I'd like to adopt the DRY principle :) and since there will be more than two requests, I'm trying to wrap that getJSON requests into an each cycle:

var elementsToGet = { // I'll reuse this to get the values elsewhere
    codiciPaese: "HY",
    regimiFiscali: "RF01",
};

$.when(
    $.each(elementsToGet, function (element, defaultValue) {
        $.getJSON(applicationUrl + "data/"+element+".json", function (json) {
            data.element = json;
            $.each(data.element, function (thisIndex, thisElement) {
                $(parent + " ."+element).append($('<option>', {
                    value: thisElement.code,
                    text: thisElement.code + " - " + thisElement.name
                }));
            });
        });
    }),
    $.Deferred(function (deferred) {
        $(deferred.resolve);
    })
).done(function () {
    $('#loading').fadeOut(800, function () {
        // something else
    });
});

The problem is that this way "deferred" is not used anymore, so the loading panel disappears before all of my data is loaded. What am I doing wrong?

Upvotes: 1

Views: 228

Answers (3)

dfsq
dfsq

Reputation: 193261

I think that you can supply multiple promises to $.when:

var promises = $.map(elementsToGet, function(element, defaultValue) {
        return $.getJSON(applicationUrl + "data/" + element + ".json", function(json) {
            $.each(data.element, function(thisIndex, thisElement) {
                $(parent + " ." + element).append($('<option>', {
                    value: thisElement.code,
                    text: thisElement.code + " - " + thisElement.name
                }));
            });
        });
    });

$.when.apply(null, promises).done(function() {
    $('#loading').fadeOut(800, function() {
        // something else
    });
});

Note, .apply(null, promises) is here because $.when expects deferred objects to be passed as $.when( d1, d2, d3 ) and not array.

Upvotes: 3

IgorAlves
IgorAlves

Reputation: 5540

If I got your question, You need call a ajax request after a ajax request and do something. Here you will have a gerenal idea. You can change based on your needs.

//The data you want to send to server side
var dt1={ 
        dt1:val1,
        dt2:$("#txt_EmailLogin").val()
    };

//Your ajax-1 request.
var request =$.ajax({//http://api.jquery.com/jQuery.ajax/
     url: "yourServer.php",
     type: "POST",
     data: dt1,
     dataType: "json"
});//End of request-1

//Ajax-1 Done catch JSON from PHP 
request.done(function(dataset){
    for (var index in dataset){ 
         dataPHPtoJsJS=dataset[index].dataPHPtoJs;
         asManyasYouWantJS=dataset[index].asYouWant;
     }

     //JavaScript conditions. Here you can control the behaivior of your html object, based  on your PHP response. HERE YOU CAN HIDE YOUR LOAD PANNEL - IF IS THE CASE.
     if(dataPHPtoJsJS){
        $( "#idYourHtmlElement" ).removeClass( "class1" )
        $( "#idYourHtmlElement" ).addClass( "class2" )
     }

    /////////////////////////////////////////////////////////////
    //Here will be your second Ajax that will be trigged after the Ajax-1 will done. Only repeat everything
    var dt2={ 
        dt3:val1,
        dt4:$("#txt_EmailLogin").val()
    };

    //Your ajax-2 request.
    var request =$.ajax({//http://api.jquery.com/jQuery.ajax/
         url: "yourServer2.php",
         type: "POST",
         data: dt2,
         dataType: "json"
        });

        request.done(function(dataset){
            for (var index in dataset){ 
                dataPHPtoJsJS=dataset[index].dataPHPtoJs;
                asManyasYouWantJS=dataset[index].asYouWant;
            }//End of for

            //Here you can call another Ajax AJAX-3, you can controll your HTML elements - HERE YOU CAN HIDE YOUR LOAD PANNEL - after the second AJAX is done
        });//End of DONE-2

    //Ajax-2 Fail 
    request.fail(function(jqXHR, textStatus) {
        alert("Request -1 failed: " + textStatus);
    });

    /////////////////////////////////////////////////////////////
});//End of AJAX-1

//Ajax-1 Fail 
request.fail(function(jqXHR, textStatus) {
            alert("Request -1 failed: " + textStatus);
}); 

Upvotes: 0

Mathieu Labrie Parent
Mathieu Labrie Parent

Reputation: 2596

How about this ?

var functionToCall = 2;
var functionCalled = 0;

$.getJSON(applicationUrl + "data/codiciPaese.json", function (json) {
    data.codiciPaese = json;
    $.each(data.codiciPaese, function (index, item) {
        $(".codiciPaese").append($('<option>', {
            value: item.code,
            text: item.code + " - " + item.name
        }));
    });
    AmIDone();
});

$.getJSON(applicationUrl + "data/regimiFiscali.json", function (json) {
    data.regimiFiscali = json;
    $.each(data.regimiFiscali, function (index, item) {
        $(".regimiFiscali").append($('<option>', {
            value: item.code,
            text: item.code + " - " + item.name
        }));
    });
    AmIDone();
});

function AmIDone() {
    functionCalled++;
    if (functionCalled == functionToCall) {
        $('#loading').fadeOut(800, function () {
            // something else
        });
    }
}

Upvotes: 0

Related Questions