I have two functions getStudentById(studentId) and getBookTitleById(bookId) where the data is retrieved via ajax calls (these functions are to be left alone)
My goal, using Deferreds:
- get the Student object,
- then get the Book Title based on the Student object's favoriteBookId property,
- then call the method showMessage(student, bookTitle) resulting in "John likes Book 222"
This example is simplified. In essence the goal is to make a certain number of ajax calls in succession, where the next call depends on the result of the previous, and at the end, offer access to ALL the resolves
code:
var getStudentById = function(studentId){
return $.Deferred(function(def){
def.resolve({name:"John",favoriteBookId:222}); //assume ajax gets Student obj
}).promise();
}
var getBookTitleById = function(bookId){
return $.Deferred(function(def){
def.resolve("Book " + bookId); //assume ajax call gets title
}).promise();
}
var showMessage = function(student, bookTitle){
alert(student.name + " likes " + bookTitle)
}
I've seen many solutions that follow the following pattern
deferred_a.then(b).then(c).then(y).then(z).done(r)
which would translate to:
getStudentById(5) //resolves with student object
.then(function(student){
return getBookTitleById(student.favoriteBookId)}
)
.done(function(bookTitle){
alert(bookTitle); //obviously this works
// how can I get reference to the student object here? so i can say:
// showMessage (student, bookTitle)
});
but i need to call the method showMessage(student, bookTitle), where the parameters are the result of each ajax call in the chain
I cannot find an (elegant) example where ALL the results of sequential Deferred calls are accessible at the end of the chain, as it the done function gets the result of the LAST then
My best solution is to wrap the second Deferred in a factory-type method, but this cant be the best solution, right? Am I missing something from the Deferred usage that should simplify this?
getStudentById(5)
.then(function(student){
return $.Deferred(function(def){
getBookTitleById(student.favoriteBookId)
.done(function(bookTitle){def.resolve({student:student, bookTitle:bookTitle})})
}).promise();
})
.done(function(studentAndBookTitle){
alert(studentAndBookTitle.student.name + " likes " + studentAndBookTitle.bookTitle);
});