3

I have an input text that takes the area as show below:

<input type="text" [(ngModel)]="areaSearch">

And, i have a list to filter based on the entered area against area_name property

<ul *ngIf="areaSearch">
    <li *ngFor="let area of areaList | filter : {area_name: areaSearch} ">
        ...
    </li>
</ul>

Am getting error like The pipe 'filter' could not be found. Can anyone help me to solve this?..

2 Answers 2

10

Angular does not have concept named filter, instead you should create your custom pipe as follows,

import { Pipe, PipeTransform } from '@angular/core';
@Pipe({name: 'filterByArea'})
export class FilterByStatusPipe implements PipeTransform {

    transform(areaList : any, areaname: string): any[] {
        if (areaList) {
            return areaList.filter((listing: any) => listing.area_name === areaname);
        }
    }
}

and use it as follows,

<ul *ngIf="areaSearch">
    <li *ngFor="let area of areaList | filterByArea:areaSearch">
        ...
    </li>
</ul>
Sign up to request clarification or add additional context in comments.

7 Comments

can't we do this in view itself like we do in AngularJs?
no you cannot do, because angualr2 does not support filters
well its a nice solution and i don't know who downvoted your answer :-\
@Sajeetharan I didn't downvote, but I think I know why it happened. You posted a partial answer without any supporting code or explanation first right? The voter probably saw your post in that state, before you fleshed out the answer with more helpful details.
@BeetleJuice No indeed i posted with example first
|
4

I would define filteredAreaList in the component as a readonly:

// this goes in the component
get filteredAreaList() {
    return this.areaList.filter(v => v.area_name === this.areaSearch)
}

This will ensure that filteredAreaList has only those elements of areaList whose area_name property matches the current areaSearch

Then in the template, just iterate over filteredAreaList

<ul *ngIf="areaSearch">
    <li *ngFor="let area of filteredAreaList ">
        ...
    </li>
</ul>

One benefit of this approach is that the logic is kept out of the template, and it is easy to extend (e.g: if in the future the displayed list depends on other component properties). I also like the pipe solution from Sajeetharan.

UPDATE: 2019-05-17

With nearly 2 more yrs of Angular under my belt since I wrote my answer, I have a slightly new perspective upon reading mine and Sajeetharan's accepted response. My solution has less overhead; it is also easier to implement; there are fewer steps -- no need to create a pipe, declare it in a module, make sure the component's module also has access to it etc. However Sajeetharan's solution will run faster especially if areaList is a big array because by default the pipe logic is only run if the inputs change.

This means that in practice once the user enters an area name, the filter will execute just once and be done, whereas with my solution, the filteredAreaList getter will execute every change detection cycle. The difference is trivial if you have only a few dozen areas, but if you have a very large set it matters.

1 Comment

can't we do this in view itself like we do in AngularJs?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.