Reputation: 115
I am having a struggle with getting jQuery deferreds to work for me.
I am attempting to chain together a number of function calls which make $.ajax
calls with jQuery .then
statements, using the pattern set out below, however each function is returning (and so the then chain continuing) before the ajax call is resolved.
// earlier code runs fine to here
})
.then(function (r) {
getCurrentYearAbsenceRequestData(); // calls function which contains a $.ajax request
})
.then(function (r) {
restructureCurrentYearAbsenceData();
});
// further processing of results
The functions called above follow this pattern:
function getCurrentYearAbsenceRequestData() {
var dfd = $.Deferred();
var today = moment();
var startOfCurrentHolidayYear = moment($clnt.holidayYearStartDate, "DD MMMM").format("DD/MM/YYYY");
var startDayOfCurrentHolidayYear = moment().dayOfYear(startOfCurrentHolidayYear)
var currentDayOfYear = moment().dayOfYear();
if (moment(today).isBefore(startOfCurrentHolidayYear)) { //checks if holiday year started last year
startOfCurrentHolidayYear = moment(startOfCurrentHolidayYear).subtract(1, "years"); //if so subtract 1 year from start of currently holiday year date
};
console.log("Start of Holiday year is " + startOfCurrentHolidayYear);
var getOrgDataQuery = $apiUrl + "/web/lists/getbytitle('AbsenceRequests')/Items?$select=Id,AssocBranch/Title,DateFrom,DateTo,EmployeeLookup/EmployeeName,EmployeeLookup/Id,AbsenceType/AbsenceTypeShort,ReviewOutcome,TotalDays,AbsenceNotes&$expand=AssocBranch/Title,EmployeeLookup/EmployeeName,AbsenceType/AbsenceTypeShort&$filter=DateFrom ge '" + startOfCurrentHolidayYear + "'";
$.ajax(_cnxRest.getRequest(getOrgDataQuery)) //calls personal library function which formats the parameter - this works OK)
.done(function (r) {
console.log("Get Org data success" + r);
var $absDataCurrentYearData = r.d.results;
$absData.allCurrentYear = $absDataCurrentYearData;
dfd.resolve();
})
.fail(function (err) {
logError(err);
});
};
return dfd.promise();
};
I am wanting the $.ajax call to resolve before the subsequent .then function progresses and would pleased to receive some intelligent advice as to where I am going wrong.
Upvotes: 1
Views: 119
Reputation: 19288
Asynchronous functions must return a promise in order to inform their callers of the asynchronism. Otherwise a caller's .then(...).then(...)
chain will continue with no regard to the asynchronism, which is the symptom described in the question.
You are just missing some returns, though the code could also be tidied somewhat.
// earlier code runs fine to here
.then(function (r) {
return getCurrentYearAbsenceRequestData();
// ^^^^^^
})
.then(function (r) {
return restructureCurrentYearAbsenceData();
// ^^^^^^
})
.fail(function (err) {
logError(err); // by logging here you will see reported errors arising from the entire chain.
});
function getCurrentYearAbsenceRequestData() {
var startOfCurrentHolidayYear = moment($clnt.holidayYearStartDate, "DD MMMM").format("DD/MM/YYYY");
if(moment(moment()).isBefore(startOfCurrentHolidayYear)) {
startOfCurrentHolidayYear = moment(startOfCurrentHolidayYear).subtract(1, "years");
};
var getOrgDataQuery = $apiUrl + "/web/lists/getbytitle('AbsenceRequests')/Items?$select=Id,AssocBranch/Title,DateFrom,DateTo,EmployeeLookup/EmployeeName,EmployeeLookup/Id,AbsenceType/AbsenceTypeShort,ReviewOutcome,TotalDays,AbsenceNotes&$expand=AssocBranch/Title,EmployeeLookup/EmployeeName,AbsenceType/AbsenceTypeShort&$filter=DateFrom ge '" + startOfCurrentHolidayYear + "'";
return $.ajax(_cnxRest.getRequest(getOrgDataQuery))
// ^^^^^^
.then(function(r) {
$absData.allCurrentYear = r.d.results;
retrun r; // make the result available to the next step in the caller's .then chain, even if it's not going to be used
// ^^^^^^
});
};
The main chain could be simplified to :
.then(getCurrentYearAbsenceRequestData) // calls function which contains a $.ajax request
.then(restructureCurrentYearAbsenceData)
.fail(function(err) {
logError(err);
});
Here, the retruns are those written within the named functions.
Upvotes: 1