I have this code in a javascript module (I'm using Require js and Knockout)
var getPersons = function(personsObservable) {
personsObservable([]);
var getOptions = {
url: 'api/persons',
type: 'GET',
dataType: 'json'
};
return $.ajax(getOptions)
.then(querySucceeded)
.fail(queryFailed);
function querySucceeded(data) {
var persons = [];
data.sort(sortPersons);
data.forEach(function (item) {
var p = new model.Person(item);
persons.push(p);
});
personsObservable(persons);
};
}
and then in another one using that module I call it like this:
function refresh() {
return dataservice.getPersons(persons).then(dataservice.getTalks(talks));
};
being getTalks another function in the dataservice module.
But I'm not sure if the result of that will be an actual promise, i.e. until I populate persons with the result of the ajax call the getTalks won't be invoked. As far as I understood calling the then method will do the trick, is that right?
Thanks
UPDATE:
So after reading the answers and further investigating into these promises stuff I came up with this, don't know if makes sense
Now the getPersons and getTalks don't populate the observable but just return the arrays, and the refresh function looks like this:
function refresh() {
return $.when(dataservice.getPersons(persons), dataservice.getTalks(talks))
.then(
//Success
function (personArgs, talksArgs) {
persons(personArgs);
talks(talksArgs);
},
//Failure
function(){
logger.log("There's been an error retrieving the data");
});
};
TI still need that this refresh returns a promise, so still doubting about it.
If the function getPersons
is well named, then it will do just that (get persons) and no more, and the two calls to personsObservable
will be made at the point that getPersons
is called.
getPersons
would thus compact down to :
var getPersons = function () {
return $.ajax({//return here to make the make the result of the $.ajax().then() chain available at the point where getPersons() is called.
url: 'api/persons',
dataType: 'json'
}).then(function (data) {
//sortPersons is presumably defined in an outer scope
return data.sort(sortPersons).map(function (item) {//return here to make the mapped array available as the promised result of getPersons.
return new model.Person(item);//return here to push elements onto the mapped array
});
});
};
Note - to keep things clean and efficient, no assignments are made within the function
and would be called, for example, as follows :
persons([]);
getPersons().then(persons).fail(queryFailed);
The entire promise chain (in shorthand) is thus $.ajax().then().then().fail();
, but split such that the first two calls in the chain are inside getPersons
, which returns an appropriate promise.
The use of $.when()
in your refresh
function makes things very slightly more complicated. With getTalks
modified in the same way as getPersons
, refresh
could be written as follows :
function refresh () {
persons([]);
talks([]);//assumed
return $.when(dataservice.getPersons(), dataservice.getTalks()).then(function (p, t) {
persons(p);
talks(t);
}, function () {
logger.log("There's been an error retrieving the data");
});
};