Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using jQuery Deferred with multiple ajax containing $.each

I am trying to create a javascript object for the following scenario

A survey interviews multiple people about food they have consumed over several meals. The object needs to be nested as follows:-

case={}
case[x].Interview={}
case[x].Interview[y].meals={}
case[x].Interview[y].meals[z].Food=[]

I am achieving that through the following codes

var $caseoffset=0
loadcases()
function loadcases() {
    $.ajax({
        url: "functions.php",data: {offset: $caseoffset,method: "getCase"},method: "post",dataType: 'json',
        success: function(result) {
            cases = result;
            loadinterview(cases[$caseoffset].fldCaseID)         
        }
    })  
}

function loadinterview($CaseID) {
    $.ajax({
        url: "functions.php",
        data: {method: "getinterview",caseid: $CaseID}, method: "post",dataType: 'json',
        success: function(result) {
            thiscase=cases[$caseoffset]
            thiscase.interviewcount=result.length
            thiscase.interviews={}

            $.each(result,function(key,val){
                thiscase.interviews[val.fldInterviewID]=val
                loadmeals(val.fldInterviewID)
            })  
        }    
    })
}
function loadmeals($InterviewID) {
    $.ajax({
        url: "functions.php",
        data: {method: "getmeal",InterviewID: $InterviewID},method: "post",dataType: 'json',
        success: function(result) {
            thiscase.interviews[parseInt($InterviewID)].mealcount = result.length
            thiscase.interviews[parseInt($InterviewID)].meals={}

            $.each(result, function(key, val) {

                thiscase.interviews[parseInt($InterviewID)].meals[parseInt(val.fldMealHistoryID)] = val
                getfoodinmeal($InterviewID, val.fldMealHistoryID)
            })
        }
    })
}

function getfoodinmeal($interviewid, $mealid) {
    $.ajax({
        url: "functions.php",data: {method: "getfoodinmeal",mealid: $mealid},
        method: "post",

        dataType: 'json',

        success: function(result){
            foodinmeal = [];

            $.each(result, function(key, val) {
                foodinmeal.push(val.fldFoodID)
            })

            thiscase.interviews[$interviewid].meals[$mealid].food = foodinmeal

        }
    })
}

Problem is that I would like to perform some calculation once all the food consumed by each interviewer has been compiled. How do I create deferred statement to address that.

like image 373
Sheils Avatar asked Sep 04 '26 12:09

Sheils


2 Answers

As of jQuery 1.5 $.ajax() returns a jqXHR implementing the Promise interface.

That means you can use it in combinaison with Promise.all() ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all )

Something like this should work:

Promise.all([
    $.ajax({
        url: "a.php"
    }),
    $.ajax({
        url: "b.php"
    }),
    $.ajax({
        url: "c.php"
    }),
]).then(function() {
    // the 3 $ajax() call are finished
})
like image 189
ben Avatar answered Sep 07 '26 01:09

ben


Above all answers are great and going to solve your problem. But calling multiple ajax calls is going to hurt performance of the site. If your not using third party API and if API is in your control, then you should change the API and make it more flexible. API should be designed in way that, you can query it with number of parameters and it will return the result in single request. E.g. in above case you can pass all the ids in single request and get the data for all of them. OR in best case scenario you just ask for case and it will return all the information you need (interview, meals and food). It will be the API's responsibility to query the data in the form you need.

like image 36
Rahul Raut Avatar answered Sep 07 '26 01:09

Rahul Raut



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!