Shruti Kapoor
Shruti Kapoor

Reputation: 1136

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?

Upvotes: 1

Views: 247

Answers (2)

danh
danh

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

uamanager
uamanager

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

Related Questions