Angular 4 Pipe Filter Angular 4 Pipe Filter angular angular

Angular 4 Pipe Filter


Here is a working plunkr with a filter and sortBy pipe. https://plnkr.co/edit/vRvnNUULmBpkbLUYk4uw?p=preview

As developer033 mentioned in a comment, you are passing in a single value to the filter pipe, when the filter pipe is expecting an array of values. I would tell the pipe to expect a single value instead of an array

export class FilterPipe implements PipeTransform {    transform(items: any[], term: string): any {        // I am unsure what id is here. did you mean title?        return items.filter(item => item.id.indexOf(term) !== -1);    }}

I would agree with DeborahK that impure pipes should be avoided for performance reasons. The plunkr includes console logs where you can see how much the impure pipe is called.


The transform method signature changed somewhere in an RC of Angular 2. Try something more like this:

export class FilterPipe implements PipeTransform {    transform(items: any[], filterBy: string): any {        return items.filter(item => item.id.indexOf(filterBy) !== -1);    }}

And if you want to handle nulls and make the filter case insensitive, you may want to do something more like the one I have here:

export class ProductFilterPipe implements PipeTransform {    transform(value: IProduct[], filterBy: string): IProduct[] {        filterBy = filterBy ? filterBy.toLocaleLowerCase() : null;        return filterBy ? value.filter((product: IProduct) =>            product.productName.toLocaleLowerCase().indexOf(filterBy) !== -1) : value;    }}

And NOTE: Sorting and filtering in pipes is a big issue with performance and they are NOT recommended. See the docs here for more info: https://angular.io/guide/pipes#appendix-no-filterpipe-or-orderbypipe


Pipes in Angular 2+ are a great way to transform and format data right from your templates.

Pipes allow us to change data inside of a template; i.e. filtering, ordering, formatting dates, numbers, currencies, etc. A quick example is you can transfer a string to lowercase by applying a simple filter in the template code.

List of Built-in Pipes from API List Examples

{{ user.name | uppercase }}

Example of Angular version 4.4.7. ng version


Custom Pipes which accepts multiple arguments.

HTML « *ngFor="let student of students | jsonFilterBy:[searchText, 'name'] "TS   « transform(json: any[], args: any[]) : any[] { ... }

Filtering the content using a Pipe « json-filter-by.pipe.ts

import { Pipe, PipeTransform, Injectable } from '@angular/core';@Pipe({ name: 'jsonFilterBy' })@Injectable()export class JsonFilterByPipe implements PipeTransform {  transform(json: any[], args: any[]) : any[] {    var searchText = args[0];    var jsonKey = args[1];    // json = undefined, args = (2) [undefined, "name"]    if(searchText == null || searchText == 'undefined') return json;    if(jsonKey    == null || jsonKey    == 'undefined') return json;    // Copy all objects of original array into new Array.    var returnObjects = json;    json.forEach( function ( filterObjectEntery ) {      if( filterObjectEntery.hasOwnProperty( jsonKey ) ) {        console.log('Search key is available in JSON object.');        if ( typeof filterObjectEntery[jsonKey] != "undefined" &&         filterObjectEntery[jsonKey].toLowerCase().indexOf(searchText.toLowerCase()) > -1 ) {            // object value contains the user provided text.        } else {            // object didn't match a filter value so remove it from array via filter            returnObjects = returnObjects.filter(obj => obj !== filterObjectEntery);        }      } else {        console.log('Search key is not available in JSON object.');      }    })    return returnObjects;  }}

Add to @NgModule « Add JsonFilterByPipe to your declarations list in your module; if you forget to do this you'll get an error no provider for jsonFilterBy. If you add to module then it is available to all the component's of that module.

@NgModule({  imports: [    CommonModule,    RouterModule,    FormsModule, ReactiveFormsModule,  ],  providers: [ StudentDetailsService ],  declarations: [    UsersComponent, UserComponent,    JsonFilterByPipe,  ],  exports : [UsersComponent, UserComponent]})export class UsersModule {    // ...}

File Name: users.component.ts and StudentDetailsService is created from this link.

import { MyStudents } from './../../services/student/my-students';import { Component, OnInit, OnDestroy } from '@angular/core';import { StudentDetailsService } from '../../services/student/student-details.service';@Component({  selector: 'app-users',  templateUrl: './users.component.html',  styleUrls: [ './users.component.css' ],  providers:[StudentDetailsService]})export class UsersComponent implements OnInit, OnDestroy  {  students: MyStudents[];  selectedStudent: MyStudents;  constructor(private studentService: StudentDetailsService) { }  ngOnInit(): void {    this.loadAllUsers();  }  ngOnDestroy(): void {    // ONDestroy to prevent memory leaks  }  loadAllUsers(): void {    this.studentService.getStudentsList().then(students => this.students = students);  }  onSelect(student: MyStudents): void {    this.selectedStudent = student;  }}

File Name: users.component.html

<div>    <br />    <div class="form-group">        <div class="col-md-6" >            Filter by Name:             <input type="text" [(ngModel)]="searchText"                    class="form-control" placeholder="Search By Category" />        </div>    </div>    <h2>Present are Students</h2>    <ul class="students">    <li *ngFor="let student of students | jsonFilterBy:[searchText, 'name'] " >        <a *ngIf="student" routerLink="/users/update/{{student.id}}">            <span class="badge">{{student.id}}</span> {{student.name | uppercase}}        </a>    </li>    </ul></div>