Filtering items by value inside ngFor without writing Pipes
Asked Answered
D

3

14

I have the following Component:

class MyComponent {
  public mode = 'v';
  readonly modes = ['v', 'a', 'd'];
  ....
}

Now I want to use an ngFor to display buttons for all modes in modes except the current mode stored in mode. I have the following code:

<button *ngFor="let othermode of modes">
  {{ othermode }}
</button>

I always want two buttons to be displayed, containing the remaining 2 modes. I tried this:

<button *ngFor="let othermode of modes.filter(elem => elem !== this.mode)">
  {{ othermode }}
</button>

but it isn't working. All questions I saw required to write a custom pipe for this feature, but isn't there any simple way to filter an array of strings, using just the values ?

Dimetric answered 21/11, 2017 at 6:45 Comment(0)
C
16

You can use :

<ng-container *ngFor="let othermode of modes">
  <button *ngIf="othermode!=mode">
    {{ othermode }}
  </button>
</ng-container>
Cheerio answered 21/11, 2017 at 7:5 Comment(1)
This can't be the right solution since why need iterating the list when you not event want to show it. Better to filter the list before.Clinton
O
23

Use a filter function to filter the data:

filterFunction(allButtons): any[] {  
    return allButtons.filter(buttom => buttom !== this.mode);
}

and in the template:

<button *ngFor="let othermode of filterFunction(modes)">
  {{ othermode }}
</button>

To filter objects, I recommend using existing component. See this thread:

::LINK EDITED::

https://stackblitz.com/edit/angular-ivy-wngx-filter

https://stackblitz.com/edit/article-demo

Ooze answered 28/4, 2018 at 0:42 Comment(4)
This is the suggested manner from Angular dev's going forward into v6+. no filter/orderBy pipes For them the decision is due to minification in production deployment as well as the significant performance issues that come with Pipes that are non-pure(re-run the pipe every update). They also commented that they prefer to drive logic away from the html and into typescript....so I'll be thinking in this manner for any future development to help prevent deprecation!Zeiler
@Zeiler seems like maybe this has changed? Your link now points to a page w/ an example of creating pipe to filter heros based on if they fly.Chronoscope
@Elysiumplain, you're right, the link was broken, now it's updated to an example implementation on stackblitzOoze
@WedsonQuintanilhadaSilva Yes, nice update with working test space link!Zeiler
C
16

You can use :

<ng-container *ngFor="let othermode of modes">
  <button *ngIf="othermode!=mode">
    {{ othermode }}
  </button>
</ng-container>
Cheerio answered 21/11, 2017 at 7:5 Comment(1)
This can't be the right solution since why need iterating the list when you not event want to show it. Better to filter the list before.Clinton
N
0

Use ng-template with ngIf, If you want to iterate the array with condition. Below is the sample code. you can find the working version here

<ng-template ngFor let-othermode [ngForOf]="modes">
<button *ngIf="othermode!=mode">
  {{ othermode }}
</button>
</ng-template>
Nanaam answered 21/11, 2017 at 7:3 Comment(2)
"let-" is only supported on template elements. errorDimetric
it's working in stackblitz. have your tried the sample?Nanaam

© 2022 - 2024 — McMap. All rights reserved.