Home:ALL Converter>Angular 4 Pipe Filter

Angular 4 Pipe Filter

Ask Time:2017-06-27T06:47:43         Author:user3523602

Json Formatter

I am trying to use a custom pipe to filter my *ngFor loop using an input field with ngModel. With my other custom pipe (sortBy), it works perfectly fine. However, the filter pipe seems to make it that none of the data appears. I'm still learning this, and I tried a few variations to no avail:

-filter: term
-filter: {{term}}
-filter: 'term'
-filter" {{'term'}}

So I think the problem may lie elsewhere in the code. If anyone can help I'd really appreciate it.

Here is my code:

HTML Component

<div style="text-align:center">
  <h1>
    Welcome to {{title}}!!
  </h1>

</div>
<h2>Please choose your favorite song: </h2>
<form id="filter">
    <label>Filter people by name:</label>
    <input type="text" name="term" [(ngModel)]="term" />
</form>


<table class="table">
    <thead>
      <tr>
        <th>Title</th>
        <th>Artist</th>
        <th>Likes</th>
      </tr>
    </thead>
    <tbody>
      <tr *ngFor="let song of songs | filter:term| sortBy: 'likes'; let i  = index">
        <td>{{song.title}}</td>
        <td>{{song.artist}}</td>
        <td>{{song.likes}} 

            <i class="fa fa-heart-o" aria-hidden="true"  *ngIf="song.likes < 1"></i>
         <i class="fa fa-heart" aria-hidden="true" *ngIf="song.likes >= 1"></i>
             <i class="fa fa-plus" aria-hidden="true" (click)="addLike(i)" ></i>
            <i class="fa fa-minus" aria-hidden="true" (click)="removeLike(i)" ></i>

          </td>
      </tr>
    </tbody>
  </table>

PIPE

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

@Pipe({
    name: 'filter',
    pure: false
})

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

Module

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

import { AppComponent } from './app.component';
import { SortByPipe } from './sort-by.pipe';
import { FilterPipe } from './filter.pipe';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { Pipe, PipeTransform } from '@angular/core'; 


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

JS COMPONENT

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

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent {
  title = 'Oxcord';
  songs = [

  {title: "Song", artist: "Artist", likes: 1},
  {title: "Chanson", artist: "Artiste", likes: 3},
  {title: "ABC", artist: "OneTwoThree", likes: 2},
  {title: "Trash", artist: "Meek Mill", likes: 0}

  ];
  addLike(input){
  this.songs[input].likes +=1;
} 
removeLike(input){
  this.songs[input].likes -=1;
} 
args="Me";
}

Author:user3523602,eproduced under the CC 4.0 BY-SA copyright license with a link to the original source and this disclaimer.
Link to original article:https://stackoverflow.com/questions/44769748/angular-4-pipe-filter
LLai :

Here is a working plunkr with a filter and sortBy pipe. https://plnkr.co/edit/vRvnNUULmBpkbLUYk4uw?p=preview\n\nAs 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\n\nexport class FilterPipe implements PipeTransform {\n transform(items: any[], term: string): any {\n // I am unsure what id is here. did you mean title?\n return items.filter(item => item.id.indexOf(term) !== -1);\n }\n}\n\n\nI 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.",
2017-06-27T00:51:29
DeborahK :

The transform method signature changed somewhere in an RC of Angular 2. Try something more like this:\n\nexport class FilterPipe implements PipeTransform {\n transform(items: any[], filterBy: string): any {\n return items.filter(item => item.id.indexOf(filterBy) !== -1);\n }\n}\n\n\nAnd 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:\n\nexport class ProductFilterPipe implements PipeTransform {\n\n transform(value: IProduct[], filterBy: string): IProduct[] {\n filterBy = filterBy ? filterBy.toLocaleLowerCase() : null;\n return filterBy ? value.filter((product: IProduct) =>\n product.productName.toLocaleLowerCase().indexOf(filterBy) !== -1) : value;\n }\n}\n\n\nAnd 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",
2017-06-26T23:06:02
Yash :

Pipes in Angular 2+ are a great way to transform and format data right from your templates.\n\nPipes 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.\n\nList of Built-in Pipes from API List Examples\n\n{{ user.name | uppercase }}\n\n\n\n\nExample of Angular version 4.4.7. ng version\n\n\n\nCustom Pipes which accepts multiple arguments.\n\nHTML « *ngFor=\"let student of students | jsonFilterBy:[searchText, 'name'] \"\nTS « transform(json: any[], args: any[]) : any[] { ... }\n\n\nFiltering the content using a Pipe « json-filter-by.pipe.ts\n\n\n\nimport { Pipe, PipeTransform, Injectable } from '@angular/core';\n\n@Pipe({ name: 'jsonFilterBy' })\n@Injectable()\nexport class JsonFilterByPipe implements PipeTransform {\n\n transform(json: any[], args: any[]) : any[] {\n var searchText = args[0];\n var jsonKey = args[1];\n\n // json = undefined, args = (2) [undefined, \"name\"]\n if(searchText == null || searchText == 'undefined') return json;\n if(jsonKey == null || jsonKey == 'undefined') return json;\n\n // Copy all objects of original array into new Array.\n var returnObjects = json;\n json.forEach( function ( filterObjectEntery ) {\n\n if( filterObjectEntery.hasOwnProperty( jsonKey ) ) {\n console.log('Search key is available in JSON object.');\n\n if ( typeof filterObjectEntery[jsonKey] != \"undefined\" && \n filterObjectEntery[jsonKey].toLowerCase().indexOf(searchText.toLowerCase()) > -1 ) {\n // object value contains the user provided text.\n } else {\n // object didn't match a filter value so remove it from array via filter\n returnObjects = returnObjects.filter(obj => obj !== filterObjectEntery);\n }\n } else {\n console.log('Search key is not available in JSON object.');\n }\n\n })\n return returnObjects;\n }\n}\n\n\n\n\nAdd 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.\n\n\n\n@NgModule({\n imports: [\n CommonModule,\n RouterModule,\n FormsModule, ReactiveFormsModule,\n ],\n providers: [ StudentDetailsService ],\n declarations: [\n UsersComponent, UserComponent,\n\n JsonFilterByPipe,\n ],\n exports : [UsersComponent, UserComponent]\n})\nexport class UsersModule {\n // ...\n}\n\n\n\n\nFile Name: users.component.ts and StudentDetailsService is created from this link.\n\n\n\nimport { MyStudents } from './../../services/student/my-students';\nimport { Component, OnInit, OnDestroy } from '@angular/core';\nimport { StudentDetailsService } from '../../services/student/student-details.service';\n\n@Component({\n selector: 'app-users',\n templateUrl: './users.component.html',\n styleUrls: [ './users.component.css' ],\n\n providers:[StudentDetailsService]\n})\nexport class UsersComponent implements OnInit, OnDestroy {\n\n students: MyStudents[];\n selectedStudent: MyStudents;\n\n constructor(private studentService: StudentDetailsService) { }\n\n ngOnInit(): void {\n this.loadAllUsers();\n }\n ngOnDestroy(): void {\n // ONDestroy to prevent memory leaks\n }\n\n loadAllUsers(): void {\n this.studentService.getStudentsList().then(students => this.students = students);\n }\n\n onSelect(student: MyStudents): void {\n this.selectedStudent = student;\n }\n\n}\n\n\n\n\nFile Name: users.component.html\n\n\n\n<div>\n <br />\n <div class=\"form-group\">\n <div class=\"col-md-6\" >\n Filter by Name: \n <input type=\"text\" [(ngModel)]=\"searchText\" \n class=\"form-control\" placeholder=\"Search By Category\" />\n </div>\n </div>\n\n <h2>Present are Students</h2>\n <ul class=\"students\">\n <li *ngFor=\"let student of students | jsonFilterBy:[searchText, 'name'] \" >\n <a *ngIf=\"student\" routerLink=\"/users/update/{{student.id}}\">\n <span class=\"badge\">{{student.id}}</span> {{student.name | uppercase}}\n </a>\n </li>\n </ul>\n</div>\n",
2018-07-25T07:55:50
yy