Reputation: 4289
If you look at showResults(), you will see it first creates a promise, then runs getSelectedIds() which returns a promise, then it makes the api call with those selected ids, which is an ajax call, then console logs sr df3 finished
. the problem im having an extreme hard time figuring out is i think i have some missing return statements somewhere, so the promise is getting resolved too early or something.
Can somebody PLEASE spot where im going wrong here, and tell me what is needed in either the getApi ajax call or the previous, or following event so that "sr df3 finished" DOES NOT happen until after the ajax call has returned its promise.
app.core.getSelectedIds = function(){
var dfd = $.Deferred();
//eliminates having to make an unnecessary ajax call if we already have them
if( $.isEmptyObject(app.core.selectedIds) ){
//gather up selected ids
$('input[type=checkbox]').each(function (key, value) {
//look for checked checkboxes only
if ($(this).is(':checked') && $(this).hasClass('results')) {
//get id from hidden input next to checkbox, set ids into an object for later use
stdIds[key] = $(this).next().attr('value');
}
});
app.core.selectedIds = stdIds;
}
dfd.resolve();
return dfd.promise();
};
app.test.getApi = function(newToken, nextPageNum){
var df1,df2;
if(nextPageNum){ app.test.nextPageNum = nextPageNum; }
df1 = app.test.ajaxCall1();
df2 = df1.then( function(){
console.log('test df2 started');
console.log(app.test.standardsObj); //the ajax calls results after being applied to the methods property
});
df2.done(function(){
console.log('test df2 finished');
});
};
app.ui.showResults = function(newToken){
var df1,df2,df3;
df1 = $.Deferred();
df2 = df1.then(function(){
console.log('sr df2 started');
return app.core.getSelectedIds(); //is a promise
});
df2.done(function(){
console.log(app.core.selectedIds);
console.log('sr df2 finished');
});
df3 = df2.then(function(){
console.log('sr df3 started');
app.test.getApi(newToken);
});
df3.done(function(){
console.log('sr df3 finished');
});
df1.resolve();
};
app.test.ajaxCall1 = function(){
var idArr = [];
//For now set up an array to cast those values to
$.each(app.core.selectedIds, function( key, value ){
idArr[key] = value;
});
return app.core.methodByRoute('ajax_call_1', {ids: idArr}, 'GET')
.done(function(retrievedResults){
app.test.standardsObj = retrievedResults;
})
};
console log output is
sr df2 started
Object { 1="498", 2="501", 3="502", more...}
sr df2 finished
sr df3 started
sr df3 finished
test df2 started
["valid data"]
test df2 finished
Upvotes: 0
Views: 73
Reputation: 664307
app.core.getSelectedIds = function(){ var dfd = $.Deferred(); … dfd.resolve(); return dfd.promise(); }
Looks like this function doesn't need to return a promise at all if it doesn't do anything asynchronous, and would resolve the deferred immediately anyway?
i think i have some missing return statements somewhere
Yes, exactly. The basic rule is: return
a promise from every function that does something asynchronous. In your case, that includes the app.test.getApi
function and the df2.then(function(){…})
callback that calls it - if the callback doesn't return anything, df3
is resolved immediately after df2
, as it doesn't know what to wait for.
Btw, you don't need that df1
- just start the chain with the first promise that a function returns.
app.core.getSelectedIds = function() {
if ($.isEmptyObject(app.core.selectedIds)) {
$('input[type=checkbox]').each(function (key, value) {
if ($(this).is(':checked') && $(this).hasClass('results')) {
stdIds[key] = $(this).next().attr('value');
}
});
app.core.selectedIds = stdIds;
}
return $.when(app.core.selectedIds); // a promise. just to start the chain.
// maybe this function needs to do
// something async in the future
};
app.test.getApi = function(newToken, nextPageNum) {
if (nextPageNum) {
app.test.nextPageNum = nextPageNum;
}
var df1 = app.test.ajaxCall1();
var df2 = df1.then( function(){
console.log('test df2 started');
console.log(app.test.standardsObj); //the ajax calls results after being applied to the methods property
});
df2.done(function(){
console.log('test df2 finished');
});
return df2;
// ^^^^^^^^^^^
};
app.ui.showResults = function(newToken) {
var df1 =app.core.getSelectedIds(); // is a promise
df1.done(function() {
console.log(app.core.selectedIds);
console.log('sr df2 finished');
});
var df2 = df1.then(function() {
console.log('sr df2 started');
return app.test.getApi(newToken);
// ^^^^^^
});
df2.done(function(){
console.log('sr df2 finished');
});
return df2;
// ^^^^^^^^^^^ just for convenience, if we want to chain something
// after a .showResults() call
};
Upvotes: 1