Reputation: 1031
I've been struggling to get this to work using the $.Deferred
object. Here is the stubbed setup.
g_plans = [];
$(function(){
// I have to use a custom ajax function, but it returns a promise obj
var pageLoadPromise.ajax{(
url: //call to webmethod
});
pageLoadPromise.done(matrix.buildGrid);
...
});
(function(matrix,$,undefined){
var matrix.buildGrid = function(components){
var gridData = data.d.components;
buildHeader(gridData);
buildRows(gridData);
};
function buildHeader(components){
$.each(components,function(key,component){
//does some stuff
if(this === that){
//do some other stuff
}
else{
getPlans(copmonent.COMPONENT_ID);
//does other stuff
}
});
}
}
function buildRows(components){
//does stuff, but uses data from getPlans
}
function getPlans(component){
var planPromise = ajax({
url: //call to webmethod
data:{ componentId:component}
planPromise.done(function(data){
g_plans.push({componentId:componentId,plans:data.d.plans});
});
}
})(window.matrix = window.matrix || {}, jQuery);
The problem is buildRows
starts before the getPlans
has time to finish it's ajax call, which is causing my issue. I have tried a few things with no success. Any help would be appreciated.
Upvotes: 1
Views: 129
Reputation: 4676
This is the easiest solution I can see:
1) Have getPlans()
return the planPromise
promise, which can then be handled back in the buildHeader()
function.
function getPlans(component) {
var planPromise = ajax({
url: //call to webmethod
data:{ componentId:component}
});
planPromise.done(function(data) {
g_plans.push({componentId: data.componentId, plans: data.d.plans});
});
return planPromise; // return the promise!
}
2) Call buildRows()
from the buildHeader()
function instead of matrix.buildgrid
using the promise returned from getPlans()
.
function buildHeader(components) {
var lastPromise;
$.each(components, function (key, component) {
lastPromise = getPlans(component.COMPONENT_ID);
});
lastPromise.done(function() {
buildRows(components);
});
}
Here's a JSFiddle illustrating the basic idea.
The second step is unnecessary, I just found it easier. The other option would be to return the lastPromise
from buildHeader()
, and handle it back in matrix.buildgrid
.
var matrix.buildgrid = function(components) {
var gridData = components;
var lastPromise = buildHeader(gridData);
lastPromise.done(function() {
buildRows(components);
});
};
function buildHeader(components) {
var lastPromise;
$.each(components, function (key, component) {
lastPromise = getPlans(component.COMPONENT_ID);
});
return lastPromise;
}
EDIT:
To handle the case of lastPromise
never getting set as a promise, you'd have to do something like this:
if (lastPromise && typeof lastPromise === 'object') {
lastPromise.done(function() {
buildRows(components);
});
} else {
buildRows(components); // or whatever needs to happen here.
}
Here's a JSFiddle including that bit in the buildHeader
function.
Upvotes: 2