Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Declaring a counting variable in angular2 template ngFor

Suppose I have an array of data as follows.

datas : [
  {
    nums : [121,222,124,422,521,6312,7141,812]
  },{
    nums : [121,222,124,422,521,6312,7141,812]
  },{
    nums : [121,222,124,422,521,6312,7141,812]
  }
]
nums = [121,222,124,422,521,6312,7141,812]

I wanted to display the even numbers in the array after a serial number like shown below.

1. 222
2. 124
3. 422
4. 6312
5. 812
6. 222
7. 124
8. 422
9. 6312
10. 812
11. 222
12. 124
13. 422
14. 6312
15. 812

But I could not figure out a way to set the indexes after the "even" check. Currently, I display the texts using the following code.

<div *ngFor="let data of datas">
  <div *ngFor="let num of data.nums; let rowIndex = index">
    <div *ngIf="num % 2 == 0">
      {{rowIndex+1}}. {{num}}
    </div>
  </div>
</div>

But it displays

2. 222
3. 124
4. 422
6. 6312
8. 812
2. 222
3. 124
4. 422
6. 6312
8. 812
2. 222
3. 124
4. 422
6. 6312
8. 812

Is there a way to set a counter that increments every time the ngIf condition is validated so that I can display with the correct indexes.

like image 582
Philip John Avatar asked Feb 05 '23 01:02

Philip John


1 Answers

You should use a pipe to filter the *ngFor. See https://angular.io/docs/ts/latest/guide/pipes.html ("Flying Heroes pipe") which gives a good example for that.

<div *ngFor="let num of (nums | evenNums); let rowIndex=index">
  {{rowIndex+1}}. {{num}}
</div>

and

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({ name: 'evenNums' })
export class EvenNumsPipe implements PipeTransform {
  transform(allNums: number[]) {
    return allNums.filter(num => num % 2 == 0);
  }
}

Also compare How to apply filters to *ngFor

Update: As far as I understand all you'd have to do is

<div *ngFor="let data of datas">
  <div *ngFor="let num of (data.nums | evenNums); let rowIndex = index">
      {{rowIndex+1}}. {{num}}
  </div>
</div>

The pipe should just filter the nums the same way, doesn't matter if it's inside a nested for or whatever.

Update 2: I have created a Plunkr to do this: https://plnkr.co/edit/NwoDPZqukKM7RyCHJudu?p=preview Seems like there is no other way than having a custom function that counts the rows so far. Angular does not support having a custom increment on a counter. I guess this is due to the guideline that there should be as minimal logic as possible in the templates.

like image 99
bergben Avatar answered Feb 16 '23 04:02

bergben