[Fixed] NaN result when I add values from different selects

Issue

In my project I have to add up the price values based on the surface that the user chooses. I don’t understand how to sum the partial cost, based on the change of the user’s choice.

sum.ts

num: Intervention
  totalScore: number

  code: Code[] = [
    {id: 1, name: "A"},
    {id: 2, name: "B"},
    {id: 3, name: "C"}
  ];

  intervention: Intervention[] = [
    {id: 1, code: this.code[0], priceA: 10, priceB: 0, priceC: 0},
    {id: 2, code: this.code[1], priceA: 20, priceB: 0, priceC: 0},
    {id: 3, code: this.code[2], priceA: 15, priceB: 5, priceC: 0}
  ]
  
  setValue(event) {
    this.num.value = event.target.value;
  }

  total() {
    this.intervention.forEach(a => {
      let p1: number
      let p2: number
      let p3: number
      if(a.surfaceType == 1) {
        p1 = a.priceA * a.value
      } else if(a.surfaceType == 2) {
        p2 = a.priceB * a.value
      } else if(a.surfaceType == 3) {
        p3 = a.priceC * a.value
      }
      a.total = p1 + p2 + p3
      this.totalScore = a.total
    })
  }

}

export class Code {
  id: number
  name: string
}

export class Intervention {
  id: number
  code: Code
  priceA: number
  priceB: number
  priceC: number
  value?: number
  surfaceType?: number = 0
  total?: number
}

sum.html

<table class="table table-hover table-bordered table-striped">
  <thead>
    <tr>
      <th scope="colgroup">Intervention:</th>
      <th scope="colgroup">Surface Type:</th>
      <th scope="colgroup">Price:</th>
      <th scope="colgroup">Size:</th>
      <th scope="colgroup">Partial cost:</th>
    </tr>
  </thead>
  <tbody>
    <ng-container *ngFor="let el of intervention; index as j">
      <tr>
        <td>{{el.code.name}}</td>

        <td>
          <select [(ngModel)]="el.surfaceType">
            <option selected disabled value="0">Select</option>
            <option value="1" [attr.disabled]="el.priceA === 0 ? 'disabled' : null">PRICE A</option>
            <option value="2" [attr.disabled]="el.priceB === 0 ? 'disabled' : null">PRICE B</option>
            <option value="3" [attr.disabled]="el.priceC === 0 ? 'disabled' : null">PRICE C</option>
           </select>
        </td>

        <td *ngIf="el.surfaceType == 0">Select</td>
        <td *ngIf="el.surfaceType == 1">{{el.priceA}}€</td>
        <td *ngIf="el.surfaceType == 2">{{el.priceB}}€</td>
        <td *ngIf="el.surfaceType == 3">{{el.priceC}}€</td>

        <td>
          <input type="number" [(ngModel)]="el.value">
        </td>

        <td *ngIf="el.surfaceType == 0">Select</td>
        <td *ngIf="el.surfaceType == 1">{{el.priceA * el.value | number: '1.0-2'}}€</td>
        <td *ngIf="el.surfaceType == 2">{{el.priceB * el.value | number: '1.0-2'}}€</td>
        <td *ngIf="el.surfaceType == 3">{{el.priceC * el.value | number: '1.0-2'}}€</td>
      </tr>
    </ng-container>
  </tbody>
</table>

<button (click)="total()">Go</button>
<div class="card">
  {{totalScore}}
</div>

This is a LIVE DEMO in Stackblitz

Solution

rook218’s answer is fine.

BUT
I found another logic issue with your total() method. Here you update only the last object’s price as total, not the sum of those 3 object’s prices. And you don’t need p1, p2, p3.

I optimized your code a little as follows.

You need to initialize a value for totalScore,

totalScore: number = 0;
total() {
    this.intervention.forEach(a => {
      let price: number;
      if (a.surfaceType == 1) {
        price = a.priceA * a.value;
      } else if (a.surfaceType == 2) {
        price = a.priceB * a.value;
      } else if (a.surfaceType == 3) {
        price = a.priceC * a.value;
      }
      this.totalScore += price;
    });
  }

Leave a Reply

(*) Required, Your email will not be published