how to filter the list using pipes in angular 2

17,738

Solution 1

Working Demo

you should do like this

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

@Pipe({
  name: 'filterlist'
})
export class FilterlistPipe implements PipeTransform {

  transform(value: any, args?: any): any {
    if(!args)
     return value;
    return value.filter(
      item => item.first_name.toLowerCase().indexOf(args.toLowerCase()) > -1
   );
  }
}

check for args is having value or not , and first time you are not going to have value for args ..that is a reason its not working

Solution 2

We can use ng2-search-filter npm.
For more details you can go through this demo: Demo Link

app.module.ts

We must install the ng2-search-filter package and then we must import it in the app.module.ts as shown below.

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';

// search module
import { Ng2SearchPipeModule } from 'ng2-search-filter';

import { AppComponent } from './app.component';

@NgModule({
  imports:      [ BrowserModule, FormsModule, Ng2SearchPipeModule ],
  declarations: [ AppComponent ],
  bootstrap:    [ AppComponent ]
})
export class AppModule { }

app.component.ts

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  title = 'Angular Search Using ng2-search-filter';
  searchText;
  heroes = [
    { id: 11, name: 'Mr. Nice', country: 'India' },
    { id: 12, name: 'Narco' , country: 'USA'},
    { id: 13, name: 'Bombasto' , country: 'UK'},
    { id: 14, name: 'Celeritas' , country: 'Canada'},
    { id: 15, name: 'Magneta' , country: 'Russia'},
    { id: 16, name: 'RubberMan' , country: 'China'},
    { id: 17, name: 'Dynama' , country: 'Germany'},
    { id: 18, name: 'Dr IQ' , country: 'Hong Kong'},
    { id: 19, name: 'Magma' , country: 'South Africa'},
    { id: 20, name: 'Tornado' , country: 'Sri Lanka'}
  ];
}

app.component.html

| filter:searchText will do the magic of filtering.

*ngFor="let hero of heroes | filter:searchText"

So let's add it in our for loop in HTML where we are actually iterating the list.

<div class="container text-center">
  <h1>{{title}}</h1>
</div>
<div class="container">
  <div class="row">
    <div class="search-hero">
      <input class="form-control" type="text" name="search" [(ngModel)]="searchText" autocomplete="off" placeholder="&#61442;  Start searching for a hero by id or name or country">
    </div>
    <table class="table table-striped">
      <thead>
      <tr>
        <th>Id</th>
        <th>Hero Name</th>
        <th>Country</th>
      </tr>
      </thead>
      <tbody>
      <tr *ngFor="let hero of heroes | filter:searchText">
        <td>{{hero.id}}</td>
        <td>{{hero.name}}</td>
        <td>{{hero.country}}</td>
      </tr>
      </tbody>
    </table>
  </div>
</div>

This will take care of filtering the data from the result list. Hope this will help you.

Solution 3

The reason Angular doesn't ship with pipes to do this, is because it will have terrible performance.

For every single row in your array, you will iterate the entire array. Repeat that possibly several times per second. This is not something you want.

Instead, declare your list like this:

allUsers: [];
filteredUsers: [];

Populate allUsers as you presently do users. Then, in every place searchText changes, iterate allUsers and add the matching users to filteredUsers. This way, if only five users match your search text, the template only needs to iterate five times.

Your loop becomes:

<ul class="user-list">
  <li *ngFor="let user of filteredUsers" class="user-list__item">
</ul>

And so on.

I should add that since I first posted this answer, I have also used the same technique whenever I wanted to reduce the amount of work done in my templates. I've found that having your template iterate only a thousand times can perform very poorly on older mobile devices and cause noticeable delays even on my beastly i7 development PC.

Share:
17,738

Related videos on Youtube

naveen
Author by

naveen

Updated on June 04, 2022

Comments

  • naveen
    naveen almost 2 years

    could you please tell me how to filter the list using pipes in angular 2

    https://stackblitz.com/edit/angular-qvtqeu?file=src%2Fapp%2Fapp.component.html

    I tried like this

    <ul class="user-list | filterlist:userenter">
      <li *ngFor="let user of users" class="user-list__item">
    

    Filter

    import { Pipe, PipeTransform } from '@angular/core';
    
    @Pipe({
      name: 'filterlist'
    })
    export class FilterlistPipe implements PipeTransform {
    
      transform(value: any, args?: any): any {
        return value.filter(
          item => item.first_name.toLowerCase().indexOf(args.toLowerCase()) > -1
       );
      }
    
    }
    

    But filtering is not working when I type on input field ?

  • naveen
    naveen almost 6 years
    ohh sorry my mistake
  • naveen
    naveen almost 6 years
    it is showing blank first time stackblitz.com/edit/…
  • Chrillewoodz
    Chrillewoodz almost 6 years
    Just return the whole list from the pipe if the query is empty.
  • serraosays
    serraosays almost 6 years
    This needs a code sample or something @vishal-biradir
  • sfors says reinstate Monica
    sfors says reinstate Monica almost 6 years
    The answers and comments above point out the issues with filtering with pipes yet we still see so many "working" solutions. And even this ng2-search-filter component using pipes. It looks like performance becomes a problem with around 5,000 or more items in the array. See stackoverflow.com/questions/44769748/angular-4-pipe-filter and stackoverflow.com/questions/39196756/….
  • artworkjpm
    artworkjpm over 4 years
    I like this comment but I'm struggling to understand how to "replace filteredUsers with the filtered version of allUsers."
  • Cobus Kruger
    Cobus Kruger over 4 years
    @artworkjpm I think I worded it badly. I'll update the answer.