You need to call .then()
instead of .done()
in the function.
Calling .then()
will return a new promise that waits for the callback (and any promise that it returns) to finish.
Note that you don't need to call $.when()
.
Question
I have a separate typescript file which I use that contains only my ajax calls.
I have a second typescript file that I am using to load up a knockout observable array
Finally I have a view that calls the knockout object and then attempts to bind the data to a drop down.
This is my ajax data call
export class ILRDataService {
public dataServiceOptions: DataServiceOptions;
public getPeriodsForCandidate() {
var urlToUse = this.dataServiceOptions.baseUrl + 'ilrdata/' +
this.dataServiceOptions.periodIdentifier +
'/AcademicPeriods/' + this.dataServiceOptions.candidateIdentifier;
return $.ajax({
url: urlToUse
});
}
}
This is called from my class. This is the method that calls the getPeriodsForCandidate method
export class AcademicPeriod {
private dataServiceOptions: DataServiceOptions;
public LoadPeriodsForCandidate() {
var self = this;
var dataService = new Ilr.ILRDataService(self.dataServiceOptions);
return dataService.getPeriodsForCandidate()
.done(function (academicPeriods) {
$.each(academicPeriods, function (index, element) {
self.Items.push(element);
console.log(element);
});
});
}
}
And finally on my view I have the following code
var academicPeriodsViewModel = new Ilr.AcademicPeriod(dataServiceOptions);
$.when(academicPeriodsViewModel.LoadPeriodsForCandidate())
.then(function() {
ko.applyBindings(academicPeriodsViewModel, document.getElementById("AcademicPeriods"));
});
My problem is in the LoadPeriodsForCandidate method of the AcademicPeriod period, the function is returning immediately, not after processing the $.each, and is causing the binding to failing in Internet Explorer.
The binding does not fail everytime. If I have the F12 developer tools open, then the binding works. But if the F12 dev tool window is closed, then the binding frequently fails. I cant see the failure message because I need to F12 window open to view the console, and the minute that happens, everything works.
No problems using the above code in Chrome or Firefox.
I have tested, and if I create a new callback function and alter my code as the following:
public LoadPeriodsForCandidate(callbackFunction) {
var self = this;
var dataService = new Ilr.ILRDataService(self.dataServiceOptions);
dataService.getPeriodsForCandidate()
.done(function (academicPeriods) {
$.each(academicPeriods, function (index, element) {
self.Items.push(element);
});
callbackFunction();
});
}
and change the code on my view to the following:
academicPeriodsViewModel.LoadPeriodsForCandidate(bindAcademicPeriods);
function bindAcademicPeriods() {
ko.applyBindings(academicPeriodsViewModel, document.getElementById("AcademicPeriods"));
}
Then everything works in IE
However I think that this is more of a kludge, and want to know how / what I need to do to change the method LoadPeriodsForCandidate so that I can successfully using the $.when().then() correctly
Solution
You need to call .then()
instead of .done()
in the function.
Calling .then()
will return a new promise that waits for the callback (and any promise that it returns) to finish.
Note that you don't need to call $.when()
.