Reputation: 1136
I have a function that has data which is a combination of promise data and simple math values. Here's the function :
_getTotalPrice = function() {
var price = 0;
// Simple Math data.
// Calculate price for channels first.
price = price + ( num_channels - 5 )*( 4);
var themepacks = cart.themepacks;
if(themepacks) {
angular.forEach(themepacks, function(pack, index) {
// data coming from a service
channelFactory.getThemePack(pack).then(function(result) {
price = price + Number(result.packPriceAmt);
console.log("price", price);
});
});
}
console.log(" Total price", price);
return price;
};
At the time of page load, the value of Total price
and price
is different. It is because the price
is loaded after promise is resolved. How can I wait till the promise is resolved before returning the value? Do I create another promise within this function?
Upvotes: 1
Views: 247
Reputation: 62676
The function must itself return a promise for the total price which is dependent on all (all
) of the created promises' resolutions.
First, a little factoring will help clear it up:
// return a promise for a theme pack price
function priceOfPack(pack) {
return channelFactory.getThemePack(pack).then(function(result) {
return Number(result.packPriceAmt);
});
}
This makes clearer the idea that we're going to collect a set of prices asynchronously. Now the loop is simpler...
_getTotalPrice = function() {
var themepacks = cart.themepacks || [];
var promises = [];
angular.forEach(themepacks, function(pack, index) {
promises.push(priceOfPack(pack));
});
var basePrice = (num_channels - 5) * 4;
// when all promises are resolved, they will be with an array of prices
return $q.all(promises).then(function(result) {
return result.reduce((a, b) => { a + b }, basePrice);
});
}
The caller must realize that the new function returns a promise and change accordingly, so...
_getTotalPrice().then(function(result) {
// result is the totalPrice
});
Upvotes: 1
Reputation: 1258
Try this:
_getTotalPrice = function() {
var price = 0;
// Simple Math data.
// Calculate price for channels first.
price = price + ( num_channels - 5 )*( 4);
var themepacks = cart.themepacks;
if(themepacks) {
angular.forEach(themepacks, function(pack, index) {
// data coming from a service
return channelFactory.getThemePack(pack).then(function(result) {
price = price + Number(result.packPriceAmt);
return $q.when(price);
});
});
}
else{
return $q.when(price);
}
};
_getTotalPrice().then(function(price){
console.log(price);
});
It'll be async function.
Upvotes: 1