2

I know that there is a lot of question about this but it really hard to find an answer that I can implement it. I want to make a function for sum a price but everytime I try to use loop it always give me length property undefined

some of topic that I try, but it still failed :

sum-of-object-properties-within-an-array

how-to-get-nested-array-length-in-javascript

how-to-get-sum-from-array-using-javascript

cannot-read-property-length-of-undefined-angular-7

this is my ts:

  allUnpaidTeam: []; //this is a variabel to store all my Json in my array

  formatPrice(value) {
    let val = (value/1)
    return val.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ".")
  }

  totalPrice() {
    let total = 0;
    for(let data of this.allUnpaidTeam){
      for(let datas of data.contest){
        let sum = datas.pricePerStudent * data.memberPerTeam;
        total+= sum;
      }
    }
    return this.formatPrice(total);
  }

this is the example of the array json:

{
  "teams": [
    {
      "student": [
        {
          "team": null,
          "_id": "5d4e891cff5e00c9d5c28af9",
          "name": "John Swasneger",
          "email": "john.s@gmail.com",
          "phone": "098778900987",
          "school": "5d4e3e258311a9c3d43569d5",
          "__v": 0
        }
      ],
      "isPaid": false,
      "_id": "5d4e8aadff5e00c9d5c28afd",
      "name": "Team Garda Frosh",
      "contest": {
        "registrationStatus": "open",
        "_id": "5d4d8b19966460a59986e13c",
        "name": "Pizza Hunt",
        "memberPerTeam": 1,
        "maxTeam": 300,
        "pricePerStudent": 185000,
        "__v": 0
      },
      "school": "5d4e3e258311a9c3d43569d5",
      "__v": 0
    },
    {
      "student": [
        {
          "team": "5d4ebcd3af8eacd1a2317bfa",
          "_id": "5d4ebc19af8eacd1a2317bf7",
          "name": "lala",
          "email": "lala@gmail.com",
          "phone": "098778900987",
          "school": "5d4e3e258311a9c3d43569d5",
          "__v": 0
        },
        {
          "team": "5d4ebcd3af8eacd1a2317bfa",
          "_id": "5d4ebc35af8eacd1a2317bf8",
          "name": "lulu",
          "email": "lulu@gmail.com",
          "phone": "098778900987",
          "school": "5d4e3e258311a9c3d43569d5",
          "__v": 0
        }
      ],
      "isPaid": false,
      "_id": "5d4ebcd3af8eacd1a2317bfa",
      "name": "Team Landing Safe",
      "contest": {
        "registrationStatus": "open",
        "_id": "5d4d8b1a966460a59986e13d",
        "name": "burger knight",
        "memberPerTeam": 2,
        "maxTeam": 151,
        "pricePerStudent": 185000,
        "__v": 0
      },
      "school": "5d4e3e258311a9c3d43569d5",
      "__v": 0
    }
  ]
}

this is my html:

              <mat-grid-list class="section-title" cols="4" rowHeight="40px">
                <mat-grid-tile><div class="table-text name last">Total</div></mat-grid-tile>
                <mat-grid-tile><div class="table-text-title">&nbsp;</div></mat-grid-tile>
                <mat-grid-tile><div class="table-text-title">&nbsp;</div></mat-grid-tile>
                <mat-grid-tile><div class="table-text price last">$ {{totalPrice()}}</div></mat-grid-tile>
              </mat-grid-list>

Can someone help me to solve this?

Rakis Friski
  • 551
  • 1
  • 7
  • 26
  • your requirement is to get `pricePerStudent * memberPerTeam` of each contest object and add this value to sum. – Akhil Aravind Aug 10 '19 at 15:58
  • `getAllUnpaidTeam` reads like the name of a method. If that's the case, then it needs to be invoked. If it's actually a property that evaluates to an array then you should rename it so it's not confusing – Aluan Haddad Aug 10 '19 at 15:59
  • yes, I want to get the total value of total price and to show it in my html – Rakis Friski Aug 10 '19 at 15:59
  • @AluanHaddad getAllUnpaidTeam is an array to add the data `getAllUnpaidGuru: [];`, I'll add it in my post – Rakis Friski Aug 10 '19 at 16:01
  • 1
    @RakisFriski OK. Well, it probably isn't initialized when the component is initially rendered. you want something like ``. However, you should rename it to something like `allUnpaidGuru` so it's not confusing. – Aluan Haddad Aug 10 '19 at 16:05
  • @AluanHaddad you're right if I write it as `getAllUnpaidTeam` it will be confusing, and I typo there the right variabel is `allUnpaidTeam` not `allUnpaidGuru` the error is still in there – Rakis Friski Aug 10 '19 at 16:18
  • the error still the same `length property undefined` – Rakis Friski Aug 10 '19 at 16:32
  • The `contest` field is an Object, not an Array. You therefore cannot make the call `for(let datas of data.contest)` – Will Alexander Aug 10 '19 at 16:36

2 Answers2

5

You can use reduce, a function is evaulated for each value, and should return a new subototal each execution.

in your case will be like that: (sorry for formatting, i’m on a mobile in this moment)

totalPrice() =>
 this.allUnpaidTeam.reduce((subtotal, item) => subtotal + item.contest.pricePerStudent * item.contest.memberPerTeam,0)
Sagar V
  • 12,158
  • 7
  • 41
  • 68
Claudio
  • 3,060
  • 10
  • 17
2

It looks like you're trying to loop over the contest Object, instead of just using its data, like so:

totalPrice() {
    let total = 0;
    for(let data of this.allUnpaidTeam){
      total += data.contest.pricePerStudent * data.contest.memberPerTeam;
    }
    return this.formatPrice(total);
  }
Will Alexander
  • 3,425
  • 1
  • 10
  • 17
  • it's work but I still got error that said `ERROR TypeError: Cannot read property 'length' of undefined` and I think it point toward `contest` since it got red underlined – Rakis Friski Aug 10 '19 at 16:49
  • I try to follow this but it seems different since my contest in the middle of `data.contest` I tried using `contest = []` as this thread pointed but it seems not work https://stackoverflow.com/questions/44689474/error-typeerror-cannot-read-property-length-of-undefined – Rakis Friski Aug 10 '19 at 16:54
  • What does `allUnpaidTeam` contain when you call `totalPrice` on it? – Will Alexander Aug 10 '19 at 17:57
  • it contain exactly as an array of JSON that I state above in the post – Rakis Friski Aug 11 '19 at 00:54