How to filter items inside “ngFor” loop, based on object property string How to filter items inside “ngFor” loop, based on object property string typescript typescript

How to filter items inside “ngFor” loop, based on object property string


Here is a sample pipe:

import { Pipe, PipeTransform } from '@angular/core';@Pipe({    name: 'matchesCategory'})export class MathcesCategoryPipe implements PipeTransform {    transform(items: Array<any>, category: string): Array<any> {        return items.filter(item => item.category === category);    }}

To use it:

<li *ngFor="let model; of models | matchesCategory:model.category" (click)="gotoDetail(model)">

===== for the plunkr example ====

You need your select changes to reflect in some variable

First define in your class a member:

selectedCategory: string;

then update your template:

<select (change)="selectedCategory = $event.target.value">   <option *ngFor="let model of models ">{{model.category}}</option></select>

last, use the pipe:

  <li *ngFor="let model; of models | matchesCategory:selectedCategory" (click)="gotoDetail(model)">

==== comments after seeing the plunker ====

I noticed you used promise. Angular2 is more rxjs oriented. So the first thing I'd change is in your service, replace:

getModels(): Promise<Model[]> {  return Promise.resolve(MODELS);}

to:

getModels(): Observable<Array<Model>> {  return Promise.resolve(MODELS);}

and

getModels(id: number): Observable<Model> {  return getModels().map(models => models.find(model.id === id);}

then in your ModelsComponent

models$: Observable<Array<Model>> = svc.getModels();uniqueCategories$: Observable<Array<Model>> = this.models$  .map(models => models.map(model => model.category)  .map(categories => Array.from(new Set(categories)));

Your options will become:

     <option *ngFor="let category; of uniqueCategories$ | async">{{model.category}}</option>

and your list:

      <li *ngFor="let model; of models$ | async | matchesCategory:selectedCategory" (click)="gotoDetail(model)">

This is a very drafty solution since you have many duplicates and you keep querying the service. Take this as a starting point and query the service only once, then derive specific values from the result you got.

If you'd like to keep you code, just implement a UniqueValuesPipe, its transform will get a single parameter and filter it to return unique categories using the Array.from(new Set(...)). You will need though to map it to strings (categories) first.