Reputation: 5404
I have an page which uses jQuery 1.11.1 and is already using Deferred and Promises.
The page does approx 13 separate ajax calls and then populates a series of radio buttons into a table. Because the ajax calls will not necessarily complete in the order defined in the table, I have implemented the following. This works:
function getSubscriptionTypes(st_id) {
var d = $.Deferred();
if(st_id){
$.ajax({
type: "POST",
url: "addUser.php",
data: { st_id: st_id },
dataType: "json"
}).done(function(p) {
d.resolve(p);
}).fail(d.reject);
return d.promise();
}
}
function loadSubscriptionTypes() {
$('.subsList').each(function() {
var st_id = $(this).closest("tr").data('stId');
var st_id = String(st_id);
var sub_types = getSubscriptionTypes(st_id).done(function(c){
$.each(c, function(k,v) {
$('#stid-'+st_id).append('<input type="radio" value="' + v.ut_id + '-' + st_id + '" data-st-id="' + st_id + '" name="stid[' + st_id + ']"> ' + v.type + ' ');
});
});
});
}
loadSubscriptionTypes();
I'm struggling to now do the following - after all the radio buttons have been appended to my table, I want to use jQuery to target them (to pre-select certain ones). I'm not sure how to do this, but imagined it's a case of using another Deferred / Promise?
So I've tried modifying the code to this:
function loadSubscriptionTypes() {
var deferredObject = $.Deferred();
// Existing code above
deferredObject.resolve();
return deferredObject.promise();
}
var promise = loadSubscriptionTypes();
promise.done(function () {
console.log("loadSubscriptionTypes() done");
});
When the page is loaded the text "loadSubscriptionTypes() done" appears in my console before all of the ajax calls have been completed.
Essentially, I don't know how to tell it to wait until all of the work in loadSubscriptionTypes()
has been done, before doing other tasks.
Please can someone offer advice or point me in the right direction?
PS - I'm aware that there may be better ways of writing the code I have, but this has been put together using what I've been able to find/learn so far, and for loading the correct radio buttons into the table, actually works.
Upvotes: 0
Views: 39
Reputation: 340055
First, ensure that getSubscriptionTypes
actually returns a Promise. There's no need to create your own $.Deferred
therein - doing so is a promise antipattern:
function getSubscriptionTypes(st_id) {
return $.ajax({
type: "POST",
url: "addUser.php",
data: { st_id: st_id },
dataType: "json"
});
}
Then, in your loadSubscriptionTypes
function, accumulate all of the returned promises into an array:
var promise = getSubscriptionTypes(st_id);
push(myArray, promise);
promise.done(function(c) {
$.each(c, function(k,v) {
...
});
});
After the outer loop, use $.when
to wait for all of those promises to be resolved:
$.when.apply($, myArray).then( ... );
Upvotes: 1