2

I am working on an Angular project where I want to catch all the encCharge to add them to give a total of all the encCharge in my cf's with a for function.

This is my array :

produits = [
    {
      cf1: {
        cfTitle: 'prInfiniti30j',
        encCharge: 12345.75,
        encBonifie: 47730.56
      },
      cf2: {
        cfTitle: 'prInfiniti30j',
        encCharge: 18400.94,
        encBonifie: 38268.56
      },
      cf3: {
        cfTitle: 'prInfiniti30j',
        encCharge: 18392.00,
        encBonifie: 30570.56
      },
      cf4: {
        cfTitle: 'prInfiniti30j',
        encCharge: 0.00,
        encBonifie: 15230.56
      },
    },
  ];

This is my for function and the things that I tried, but I can't get to what I am looking for.

ngOnInit(){
for (let testing in this.produits[0]) {
  console.log(this.produits[0].cf1.encBonifie);
  // console.log(this.produits[0].testing.encCharge);
  // console.log(testing.encCharge);
}`   

This is the resultat that I expect :

let totalEncCharge = this.produits[0].cf1.encCharge + 
this.produits[0].cf2.encCharge + this.produits[0].cf3.encCharge + 
this.produits[0].cf4.encCharge ;
console.log(totalEncCharge);

Thank you for your help

Adley Slb
  • 47
  • 1
  • 8
  • Instead of this: `console.log(this.produits[0].cf1.encBonifie);`, use the `testing` variable like: `console.log(this.produits[0][testing].encBonifie);` – Rajesh Aug 01 '19 at 13:31
  • Consider just logging `console.log(JSON.stringify(testing))` within the `for` loop. Also not that using `for..in` for arrays is bad practice. See [Why is using “for…in” with array iteration a bad idea?](https://stackoverflow.com/q/500504/215552) – Heretic Monkey Aug 01 '19 at 13:31

4 Answers4

3

You can also try using Object.keys

var total = 0;
Object.keys(this.produits[0]).map(item=>{
  total+=this.produits[0][item].encCharge });
console.log(total);

*Edit: If you do not want any value returned but instead set some other attributes as in the example it is better to use forEach instead of map

  • Thank you for your help!! This is what I was looking for. – Adley Slb Aug 01 '19 at 13:54
  • Good solution, for iterating without wanting to transform something (but for the side-effects as in here) use `forEach` instead of `map` though. – claasic Aug 01 '19 at 13:58
  • Yes you are right, using `forEach` is the better approach. – Eftychios Karagiorgis Aug 01 '19 at 14:01
  • Do you have an idea of why I can't call the variables in my HTML? Like when I {{ total }} it don't show anything on the HTML page, is it in the right place in the ngOnInit or it should be on the constructor? Thanks for your help – Adley Slb Aug 02 '19 at 09:24
  • 1
    To be able to use it in the template it needs to be a class attribute, that is, defined outside of any methods of the class. Declare a variable such as `public total: number;` under your class declaration and then do `this.total = total` under your calculation. – Eftychios Karagiorgis Aug 02 '19 at 10:00
1

Please have look I hope it's helpful.

ngOnInit(){
    let totalEncCharge = 0;
    for (let i = 0 ; i < this.produits.length; i++) {
       let key = 'cf'+(i+1);
       totalEncCharge = totalEncCharge + this.produits[i].key.encCharge
    }
    console.log(totalEncCharge);   
}
Sanat Gupta
  • 1,086
  • 1
  • 10
  • 16
  • 1
    i think totalEncCharge will only load last value in loop, and should be like this? ``` let totalEncCharge = 0; for (let i = 0 ; i < this.produits.length; i++) { totalEncCharge =+ this.produits[i].cf1.encBonifie } ``` – Muhammed Moussa Aug 01 '19 at 13:36
  • First off, you are summing encBonifie which is wrong. Secondly, you are iterating over the array that only contains a single element but not over the object keys so even if you did replace encBonifie with encCharge, the result would still be wrong. – claasic Aug 01 '19 at 13:49
  • Hello, thank you for your help but this will not give me the total of all the encCharge of all my cf no? – Adley Slb Aug 01 '19 at 13:52
  • @AdleySlb I updated code please check once Thank you. – Sanat Gupta Aug 01 '19 at 13:53
  • @assoron please have a look now everything working fine and thanks – Sanat Gupta Aug 01 '19 at 13:54
  • `produits` has a length of 1. You have to iterate the keys of the object at index 0. Also instead of generating key as a variable, you can just iterate over variable key names with `[key]` instead of `.key`. – claasic Aug 01 '19 at 13:55
1

The following should work via Object.values() to get the values from the inner object first. After that you can use reduce to simply sum them together.

var produits = [{cf1:{cfTitle:'prInfiniti30j',encCharge:12345.75,encBonifie:47730.56},cf2:{cfTitle:'prInfiniti30j',encCharge:18400.94,encBonifie:38268.56},cf3:{cfTitle:'prInfiniti30j',encCharge:18392.00,encBonifie:30570.56},cf4:{cfTitle:'prInfiniti30j',encCharge:0.00,encBonifie:15230.56},},]

let totalEncCharge = Object.values(produits[0]).reduce((a,c) => a += c.encCharge, 0)

console.log(totalEncCharge);

This is one way how you can iterate your data structure with for ... in:

var produits = [{cf1:{cfTitle:'prInfiniti30j',encCharge:12345.75,encBonifie:47730.56},cf2:{cfTitle:'prInfiniti30j',encCharge:18400.94,encBonifie:38268.56},cf3:{cfTitle:'prInfiniti30j',encCharge:18392.00,encBonifie:30570.56},cf4:{cfTitle:'prInfiniti30j',encCharge:0.00,encBonifie:15230.56},},];

let totalCharge = 0;
for (let key in produits[0]) {
 totalCharge += produits[0][key].encCharge;
}

console.log(totalCharge)
claasic
  • 1,050
  • 6
  • 14
  • 1
    You might want to add a check with `hasOwnProperty` when using `for ... in` to protect against side effects. Take a look at this question: https://stackoverflow.com/questions/12735778/for-in-and-hasownproperty – Reactgular Aug 01 '19 at 14:02
1

You can use a reduce method to aggregate a total.

const pluck = (a) => a.encCharge;
const sum = (a, b) => a + b;
const total = Object.values(this.produits[0])
                    .map(pluck)
                    .reduce(sum, 0);
Reactgular
  • 52,335
  • 19
  • 158
  • 208