Reputation: 62714
I have two url endpoints say: "fruitInfo" and "fruitDetails"
I want to return an object that contains:
var fruitInfoDetails = {"fruitInfo": <contents of fruitInfo response data>,
"fruitDetails": <contents of fruitDetails response data>}
Inside a service I call:
var fruitInfoDetails = {};
this.getFruitInfo()
.then(function(data) {
fruitInfoDetails['fruitInfo'] = data;
this.getFruitDetails(data.nameOfFruit).then(function(data) {
fruitInfoDetails['fruitDetails'] = data;
})
});
Assume the this.getFruitInfo() and this.getFruitDetauls() contains functions that return the $http promise going to each of those endpoints.
What is the proper/elegant way to do this? If there is a function that I could pass a list of fruits "[Apple, Pear, Orange]", and it could return me a list of fruitInfoDetails objects, that would be perfect.
Upvotes: 2
Views: 1097
Reputation: 31632
You can make your own promise using the $q service, and resolve it when the 2nd call completes.
angular.module('mymodule').factory('FruitService', function($http, $q) {
return {
getFruitInfoDetails: function() {
// make our own promise
var deferred = $q.defer();
// 1st call
$http.get("fruitInfo").then(function(fruitInfo) {
// 2nd call
$http.get("fruitDetails").then(function(fruitDetails) {
deferred.resolve({
fruitInfo: fruitInfo,
fruitDetails:fruitDetails
});
});
});
return deferred.promise;
}
};
});
You can also use $q.all() in order to wait for both requests to finish before resolving. It result in less indentation.
angular.module('mymodule').factory('FruitService', function($http, $q) {
return {
getFruitInfoDetails: function() {
// make our own promise
var deferred = $q.defer();
// 1st call
var infoPromise = $http.get("fruitInfo");
var detailsPromise = $http.get("fruitDetails");
$q.all([infoPromise, detailsPromise]).then(function(data) {
deferred.resolve({
fruitInfo: data[0],
fruitDetails: data[1]
})
});
return deferred.promise;
}
};
});
The requested retrieving a list of given fruits:
angular.module('mymodule').factory('FruitService', function($http, $q) {
return {
getFruitInfoDetails: function(fruit) {
// make our own promise
var deferred = $q.defer();
// we'll asume that you can put the fruit as part of the path
var infoPromise = $http.get("fruitInfo/" + fruit);
var detailsPromise = $http.get("fruitDetails/" + fruit );
$q.all([infoPromise, detailsPromise]).then(function(data) {
deferred.resolve({
fruitInfo: data[0],
fruitDetails: data[1]
})
});
return deferred.promise;
},
getFruitList: function(fruits) {
var deferred = $q.defer();
// map our list of fruits to a list of the promises of fruit info
var allPromises = fruits.map(function (fruit) {
return this.getFruitInfoDetails(fruit);
});
// wait for all the fruits to be resolved then just resolve our own promise
$q.all(allPromises).then(function(allTheFruitInfoDetails) {
deferred.resolve(allTheFruitInfoDetails);
});
return deferred.promise;
}
};
});
Upvotes: 6