0

Might be the end of the work day, might be the lack of coffee, but I just can't seem to come up with the correct idea for this.

I have an array with +- 180 rows of order data. Now I would like to calculate the totals of the numbers to show them in the footer of my grid. Can someone help me out?

Array looks something like this, yet much bigger:

[{title: 'title', description: 'description', someNumber: 'someNumber', otherNumber: 'otherNumber'},{title: 'title', description: 'description', someNumber: 'someNumber', otherNumber: 'otherNumber'}]

Here is my code:

var totalsRow = [];

this.someService.data().subscribe(newData => {
      this.data = newData;

      for (let row of newData) {
        for (let col of this.cols) { //this.cols are all the fields in my array
          if (this.isNumber(row[col.field])) { //This generates row[someNumber]
            //Calculate total and push field to totalsRow
            //So that I can loop through it in my HTML file.
          } else {
            //Push empty field to totalsRow
          }
        }
      }
    });

this.cols looks something like this:

[{field: 'title', header: 'Nice header title', visible: true, isNumber: false}, 
{field: 'someNumber', header: 'Nice header title', visible: true, isNumber: true}]

This is my HTML. I want to add a TFOOT with the totals of each field which is a number:

       <thead>
          <tr>
            <ng-container *ngFor="let col of cols">
              <th *ngIf="col.visible" class="text-uppercase small-label" style="white-space: nowrap;">
                <div style="resize:both; overflow: auto; display:block">
                  {{col.header}}
                </div>
              </th>
            </ng-container>
          </tr>
        </thead>
        <tbody>
          <tr *ngFor="let rowData of data" (click)="onRowSelect(rowData)">
            <ng-container *ngFor="let col of cols">
              <td *ngIf="col.visible" [ngClass]="{'text-center': col.isCentral}">
                <span>{{rowData[col.field]}}</span>
              </td>
            </ng-container>
          </tr>
        </tbody>

What I want to achieve:

<tfoot>
      <tr *ngFor="let rowData of totalsRow">
        <td *ngIf="col.visible">
          <span>{{rowData[col.field]}}</span>
        </td>
      </tr>
    </tfoot>

Thanks in advance.

Matheno
  • 4,112
  • 6
  • 36
  • 53

3 Answers3

0

If the key is always someNumber

totalsRow = 0;

...

newData.forEach(datum => {
   if(datum.someNumber){
      this.totalsRow += datum.someNumber;
   }
})
Wandrille
  • 6,267
  • 3
  • 20
  • 43
0

You have to bring out the totalsRow definition. If you declare it inside the subscribe the scope stays there and you can't access it.

...
var totalsRow = [];
this.someService.data().subscribe(newData => {
...
0

Ah well, found a solution myself. I don't know if this would be the most neat answer, but it works for now:

I added a property total to my array of columns, and calculated the total per column.

for (let col of this.cols) {
        if (col.isNumber) {
          col.total = newData.reduce((a, b) => (a + b[col.field]), 0);
        } 

       <tfoot>
          <tr>
            <ng-container *ngFor="let col of cols">
              <td *ngIf="col.visible">
                <span *ngIf="col.isNumber">{{col.total | currency: 'EUR'}}</span>
              </td>
            </ng-container>
          </tr>
        </tfoot>
Matheno
  • 4,112
  • 6
  • 36
  • 53
  • 1
    You can make it more clean using [destrcturing assignment](https://stackoverflow.com/questions/54605286/what-is-destructuring-assignment-and-its-uses/54605288#54605288) – Code Maniac Mar 14 '19 at 16:07