Shruti Kapoor Shruti Kapoor - 4 months ago 8
AngularJS Question

AngularJS: Function with promise and non-promise data

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?

Answer

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
});
Comments