11

How can I calculate the total amount from an array?

I pass data to the child component as prop, and I am stuck here. When I console log prop, it returns a very complicated object . I tried this.values.reduce() function but it does not work.

<template>
<tr v-for="value in values"  >
      <th scope="row">{{$index+1}}</th>
      <td>{{value.name}}</td>
      <td>-</td>
      <td>${{value.total}}</td>
    </tr>
<tr>
    <th></th>
    <td><strong>Total:{{total}}</strong></td>
    <td>-</td>
    <td>-</td>
    </tr>
</template>

<script>

export default {



    props: ['values'],

      ready: function() {

    }

}
</script>
user2954463
  • 2,362
  • 2
  • 23
  • 37
OMahoooo
  • 427
  • 3
  • 9
  • 19

3 Answers3

18

In case anyone else is in the same situation as me I thought I'd add this answer. I needed to get the values from nested objects then push them to an array before reducing them:

total: function(){

  let total = [];

  Object.entries(this.orders).forEach(([key, val]) => {
      total.push(val.price) // the value of the current key.
  });

  return total.reduce(function(total, num){ return total + num }, 0);

}

This uses ES7 .entries to loop through the object which looked like this:

orders = {
    1: {title: 'Google Pixel', price: 3000},      
    2: {title: 'Samsung Galaxy S8', price: 2500},
    3: {title: 'iPhone 7', price: 5000}
  }

You can then display the total in your template with:

<span> {{total}} </span>
Pixelomo
  • 6,373
  • 4
  • 47
  • 57
  • 4
    Is there any reason you pushed all the values to an array instead of just summing them like: `Object.entries(this.orders).forEach(([key, val]) => { total+=(val.price) });`? – Austin Schmidt Nov 02 '17 at 16:13
  • hmm good question, I think possibly I was using the array to also populate the cart data so I had itemised billing – Pixelomo Nov 04 '17 at 00:54
5
var payments = new Vue({
            el: "#payments",
            data: {
                payments: [
                    { name: "houseRent", amount: 1000, is_paid: true },
                    { name: "houseRent", amount: 1500, is_paid: true },
                    { name: "houseRent", amount: 1200, is_paid: false },
                    { name: "houseRent", amount: 1070, is_paid: true },
                    { name: "houseRent", amount: 1040, is_paid: false }
                ]
            },
            computed: {
                totalAmount: function () {
                    var sum = 0;
                    this.payments.forEach(e => {
                        sum += e.amount;
                    });
                    return sum
                }
            }
        });`
3

As you proposed, you could use the Array#reduce function. Starting from this example on SO, you could adapt it to your needs and only add value.total to the sumtotal.

To compute the total of all values, you can use computed properties, which will display as {{ total }} in your template:

<script>

export default {



    props: {
        values: {
            type: Array,
            default: []
        },
    }
    ready: function() {

    },
    computed: {
        total: function() {
            if (!this.values) {
                return 0;
            }

            return this.values.reduce(function (total, value) {
                return total + Number(value.total);
            }, 0);
        }
    }

}
</script>

Note: This will of course only work, if value.total is a unitless number (e.g. 1, not '1 USD'). Otherwise you would need to strip the in the reduce function as well.

mcherm
  • 23,999
  • 10
  • 44
  • 50
nils
  • 25,734
  • 5
  • 70
  • 79
  • Thank you for your answer but this function returns : 0100200 it should return 300 , besides it gave warning , Error when evaluating expression "function total() { return this.values.reduce(function (total, value) { return total + value.total; }, 0); }": TypeError: this.values.reduce is not a function – OMahoooo Aug 24 '16 at 07:42
  • 1
    Please read: `This will of course only work, if value.total is a unitless number`. Your values need to be Numbers, otherwise you need to transform them into Numbers. I've added an example. – nils Aug 24 '16 at 07:45
  • 1
    Is it possible, that `this.values` is not an Array? Or not defined? You should probably add a default value. I've added an example as well (including prop validation). – nils Aug 24 '16 at 07:46
  • thank you its works . When i check prop validation it gave warning : Invalid prop: type check failed for prop "values". Expected Array, got String. i changed prop validation as String then it gave me same warning with Expected String got Array error .. Why is it happening? – OMahoooo Aug 24 '16 at 07:55
  • Not sure. What is the actual value of `values` before you pass it into your component? – nils Aug 24 '16 at 08:14