srujana
srujana

Reputation: 453

Pipe is not working for search filter in Angular4

Iam new to Angular4.Iam working on filters.I need to display the searched items entered in the input search box.For this I have used pipe for filtering.But it doesnot work.Below is my code:

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

@Pipe({
  name: 'searchFilter',
    pure: false
})
export class SearchFilterPipe implements PipeTransform {

 transform(items: any[], term): any {
        console.log('term', term);
      
        return term 
            ? items.filter(item => item.title.indexOf(term) !== -1)
            : items;
    }
}
<div class="container">
        <h3 class="animated wow zoomIn" data-wow-delay=".5s">New Collections</h3>
        <p class="est animated wow zoomIn" data-wow-delay=".5s">Shop here what you want within minutes of time.</p>
        <input type="text" class="form-control" name="term" [(ngModel)]="term">
        <div style="float:right">
            <pagination-controls (pageChange)="p=$event"></pagination-controls>
        </div>
        <div class="new-collections-grids" style="background-color:white;">
            <div class="col-md-3 new-collections-grid" *ngFor="let data of productsList| searchFilter : term |paginate: {itemsPerPage:8,currentPage: p}" style="background-color:white;">
                <div class="col-md-12 new-collections-grid1 animated wow slideInUp" data-wow-delay=".5s" style="width:285px;height:350px;">
                    <div class="new-collections-grid1-image" align="center">

                        <a routerLink="/productdetails" class="product-image"><img src="{{data.images[0].src}}" alt=" " style="text-align:center" height="130" width="auto" /></a>
                        <div class="new-collections-grid1-image-pos">
                            <a routerLink="/productdetails">Quick View</a>
                        </div>

                    </div>
                    <br>
                    <table align="center">
                        <tr style="height:30px"><span routerLink="/productdetails">{{data.name}}</span></tr>
                        <tr>
                            <td> PRICE<span class="item_price"> {{data.regular_price}}</span></td>
                        </tr><br>
                        <tr>
                            <p><a class="item_add" routerLink="/productdetails" style="border:1px solid red;color:red;padding:6px;">Add to cart </a></p>
                        </tr>
                    </table>
                </div>

            </div>
            <div class="clearfix"> </div>
        </div>
        <br>
        <div style="float:right">
            <pagination-controls (pageChange)="p=$event"></pagination-controls>
        </div>
    </div>

I have imported all the files correctly.Where I did the mistake?Please help me

Upvotes: 1

Views: 1078

Answers (2)

SaiSurya
SaiSurya

Reputation: 1116

This happens mainly when pagination pipe result interfere with Search pipe. I solved this issue by storing the initial array that comes to search pipe.Here is snippet of my code.

Solution 1

  storedArray:Array<any> = [];
  transform(value: any, opt?: opt): any {
  //If stored Array length is 0 then it means this is the first time
   if(this.storedArray.length == 0){
   this.storedArray = value;
   }
   /*You search filter code comes here which filters stored array not the value that 
   comes through pipe*/ 
   return this.storedArray.filter((item) => {
   //Your logic
    });
   }

Note: If you have load more functionality which adds more data later then you have to add another condition to the if clause that is:

 //This will update whenever data is more than the stored data
 if(this.storedArray.length < values.length){
   this.storedArray = value;
   }

Solution 2

I have developed a library called ngconf-pagination which does both search and pagination with single pipe.This will solve the pagination result affecting search result.

Upvotes: 0

Prasanna
Prasanna

Reputation: 1751

You should try as follows

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

@Pipe({
 name: 'searchFilter',
 pure: false
}) 
export class SearchFilterPipe implements PipeTransform {

transform(items: any, term:string): any {
 if(items.length === 0 || term === ''){
    return items;
 }
 const resultArray = [];
 for(const item of items) {
   if(item.title == term){
      resultArray.push(item);
   }
  }
  return resultArray;
}//end of pipe

byDefault pure is true.That means untill and unless filter input won't be changed pipe is not going to be triggered. but if you put 'pure:false' this will trigger respective filter whenever data from the component is getting changed, But this might affect performance as for many times filter is going to trigger. I think this might help you.

Upvotes: 1

Related Questions