0

I have an array of products, each product has a price. I want to create a filter to calculate the total price of all products. The problem is that I can't use forEach() since I'm in a callback function. My question is, is there a function that does something like myArray.(intheobject).price, or a way to manage the callback and get the right results?

this.productList = [
    {
      type: 'chocolate',
      pack: '3',
      price: 5,
      checkState: false
    },
    {
      type: 'chocolate',
      pack: '5',
      price: 7,
      checkState: false
    },
    {
      type: 'chocolate',
      pack: '10',
      price: 10,
      checkState: false
    },
    {
      type: 'honey',
      pack: '3',
      price: 5,
      checkState: false
    },
    {
      type: 'honey',
      pack: '5',
      price: 7,
      checkState: false
    },
    {
      type: 'honey',
      pack: '10',
      price: 10,
      checkState: false
    },
    {
      type: 'candy',
      pack: '3',
      price: 5,
      checkState: false
    },
    {
      type: 'candy',
      pack: '5',
      price: 7,
      checkState: false
    },
    {
      type: 'candy',
      pack: '10',
      price: 10,
      checkState: false
    }
  ]


.filter('calculateTotal', function(){
  var totalCost = 0;
  return function(input){
    return totalCost + ???
  }    
})

After PierreDuc's answer, my filter is this:

.filter('calculateTotal', function(){
  return function(input){
    return input.reduce((total, item) => item.price + total, 0);
  }    
})

4 Answers 4

2

You can use the reduce method for this:

const totalPrice = [{
    type: 'chocolate',
    pack: '3',
    price: 5,
    checkState: false
  },
  {
    type: 'chocolate',
    pack: '5',
    price: 7,
    checkState: false
}].reduce((total, item) => item.price + total, 0);

Filter is used to, like the name suggests, filter the current array based on a the return value of the provided method.

With reduce you can transform your array based on an input, 0 in this case. This gets assigned to the total parameter of the passed method, where the item is every item in your array. The value you return from that method will be the new value for the total parameter.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks you for you quick reply I had been trying to figure this out for a couple hours. I have updated my post with the modified correct filter.
1

The filter callback can access each element. So you need to create a global variable, outside the callback function and add the value of each element in the callback function to that global variable. See filter documentation.

this.totalCost = 0;

this.productList = [
    {
      type: 'chocolate',
      pack: '3',
      price: 5,
      checkState: false
    },
    {
      type: 'chocolate',
      pack: '5',
      price: 7,
      checkState: false
    },
    {
      type: 'chocolate',
      pack: '10',
      price: 10,
      checkState: false
    },
    {
      type: 'honey',
      pack: '3',
      price: 5,
      checkState: false
    },
    {
      type: 'honey',
      pack: '5',
      price: 7,
      checkState: false
    },
    {
      type: 'honey',
      pack: '10',
      price: 10,
      checkState: false
    },
    {
      type: 'candy',
      pack: '3',
      price: 5,
      checkState: false
    },
    {
      type: 'candy',
      pack: '5',
      price: 7,
      checkState: false
    },
    {
      type: 'candy',
      pack: '10',
      price: 10,
      checkState: false
    }
  ]
var self = this;
angular.module('myReverseFilterApp', [])
.filter('calculateTotal', function(){
      return function(input) {
           self.totalCost += input.price;
      }
})

You can then access the totalCost variable in your html. It is not possbile to return the totalCost from a filter function becaus this function gets applied to each element of the array. It is possible that the syntax is not correct, but I guess you get the gist.

Comments

1

const productList = [
    {
      type: 'chocolate',
      pack: '3',
      price: 5,
      checkState: false
    },
    {
      type: 'chocolate',
      pack: '5',
      price: 7,
      checkState: false
    },
    {
      type: 'chocolate',
      pack: '10',
      price: 10,
      checkState: false
    },
    {
      type: 'honey',
      pack: '3',
      price: 5,
      checkState: false
    },
    {
      type: 'honey',
      pack: '5',
      price: 7,
      checkState: false
    },
    {
      type: 'honey',
      pack: '10',
      price: 10,
      checkState: false
    },
    {
      type: 'candy',
      pack: '3',
      price: 5,
      checkState: false
    },
    {
      type: 'candy',
      pack: '5',
      price: 7,
      checkState: false
    },
    {
      type: 'candy',
      pack: '10',
      price: 10,
      checkState: false
    }
  ]
let totalPrice = productList.reduce(function(sum, currentValue, currentIndex, array) {
  return sum+currentValue['price']
},0);
console.log(totalPrice)

Comments

0

You can do as following, First get the list of all the prices and store it in an array, and then use the reduce function to perform the action on prices also read the documentation of reduce function:

reduce documentation

let pricesList = [];
productList.forEach(product => {

    pricesList.push(product['price']);

})

let sumPrice = pricesList.reduce((priceA, priceB) => priceA + priceB, 0);

1 Comment

That's some extra code that could be avoided. My question has been answered, if you check I have already updated my post with the provided answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.