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";
}
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.