-1

In the below component view,

<h2>Topic listing</h2>

<form id="filter">
  <label>Filter topics by name:</label>
  <input type="text" [(ngModel)]="term">
</form>

<ul id="topic-listing">
  <li *ngFor="let topic of topics | filter: term">
    <div class="single-topic">
      <!-- Topic name -->
      <span [ngStyle]="{background: 'yellow'}">name - {{topic.name}}</span>
      <!-- Topic type -->
      <h3>{{topic.type}}</h3>
    </div>
  </li>
</ul>

Custom filter syntax is: let topic of topics | filter: term

where custom filter is:

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

@Pipe({
  name: 'filter'
})

export class FilterPipe implements PipeTransform {

  transform(topics: any, term: any): any {
    // check if search term is undefined
    if(term === undefined) return topics;
    return topics.filter(function(topic){ // javascript filter(function)
      // if below is false, then topic will be removed from topics array
      return topic.name.toLowerCase().includes(term.toLowerCase());
    })
  }

}

the component class maintains data for topics:

export class DirectoryComponent implements OnInit {
  topics = [
    {type:"Fiction", name:"Avatar"},
    {type:"NonFiction", name:"Titanic"},
    {type:"Tragedy", name:"MotherIndia"},
  ];
  constructor() { }

  ngOnInit() {
  }

}

Edit: Without form tag, code works fine.

  <label>Filter topics by name:</label>
  <input type="text" [(ngModel)]="term">

Why custom filter FilterPipe does not filter term provided in input element?

overexchange
  • 15,768
  • 30
  • 152
  • 347

1 Answers1

1

Add brackets to your filter condition

<ul id="topic-listing">
  <li *ngFor="let topic of (topics | filter: term)">
    <div class="single-topic">
      <!-- Topic name -->
      <span [ngStyle]="{background: 'yellow'}">name - {{topic.name}}</span>
      <!-- Topic type -->
      <h3>{{topic.type}}</h3>
    </div>
  </li>
</ul>

Check the TS file

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

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  name = 'Angular 5';
  term : any = "avatar";
  topics = [
    {type:"Fiction", name:"Avatar"},
    {type:"NonFiction", name:"Titanic"},
    {type:"Tragedy", name:"MotherIndia"},
  ];
}

Remove the word function and change it to below code. refer the working version here

return topics.filter((topic)=>{ 
      return topic.name.toLowerCase().includes(term.toLowerCase());
    })

update - root cause of the issue

if you want to use NgModel inside the form tags, either the name attribute must be set or the form control must be defined as 'standalone' in ngModelOptions

Prithivi Raj
  • 2,658
  • 1
  • 19
  • 34