0

While following a tutorial to filter data using angular2 pipes, got below error

EXCEPTION: Error in ./PmProductsComponent class PmProductsComponent - inline template:20:28 caused by: value.filter is not a function

Is anyone able to shed some light as to why value.filter is not a function. It seems to align with the tutorials syntax, I am thinking perhaps an update came out that requires something different?

PIPE

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

@Pipe( {
    name: 'productFilter'
})
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;
    }

}

Component:

import { Component, OnInit } from '@angular/core';
import {IProduct} from './product';

@Component({
  selector: 'app-pm-products',
  templateUrl: './pm-products.component.html',
  styleUrls: ['./pm-products.component.css']
})
export class PmProductsComponent implements OnInit {
  pageTitle: string = 'Product List';
  imageWidth: number = 50;
  imageMargin: number = 2;
  showImage: Boolean = false;
  listFilter: string = 'cart';
  products: IProduct[] = [
        {
        "productId": 1,
        "productName": "Leaf Rake",
        "productCode": "GDN-0011",
        "releaseDate": "March 19, 2016",
        "description": "Leaf rake with 48-inch wooden handle.",
        "price": 19.95,
        "starRating": 3.2,
        "imageUrl": "http://openclipart.org/image/300px/svg_to_png/26215/Anonymous_Leaf_Rake.png"
    },
    {
        "productId": 2,
        "productName": "Garden Cart",
        "productCode": "GDN-0023",
        "releaseDate": "March 18, 2016",
        "description": "15 gallon capacity rolling garden cart",
        "price": 32.99,
        "starRating": 4.2,
        "imageUrl": "http://openclipart.org/image/300px/svg_to_png/58471/garden_cart.png"
    },
  ]

  toggleImage() : void {
    this.showImage = !this.showImage;

  }
  constructor() { }

  ngOnInit() {
    console.log('In OnInit');
  }

}

HTML

<div class = 'panel panel-primary'>
  <div class = 'panel-heading'>
    {{pageTitle}}
  </div>
    <div class ='panel-body'>
            <div class = 'row'>
                <div class = 'col-md-2'> Filter by:</div>
                <div class = 'col-md-4'>
                    <input type = 'text' 
                    [(ngModel)]='listFilter'/>
                </div>
            </div>
            <div class = 'row'>
                <div class = 'col-md-6'>
                    <h3>Filtered by:{{listFilter}}</h3>
                </div>
            </div>

            <div class = 'table-responsive'>
                <table class = 'table' 
                            *ngIf='products && products.length | productFilter:listFilter'>
                    <thead>
                        <tr>
                            <th>
                                <button class = 'btn btn-primary'
                                (click) = 'toggleImage()'>
                                 {{showImage ? 'Hide' : 'Show'}} Image
                                </button>
                            </th>
                            <th>Products</th>
                            <th>Code</th>
                            <th>Available</th>
                            <th>Price</th>
                            <th>5 Star Rating</th>

                        </tr>
                    </thead>
                    <tbody>
                        <tr *ngFor='let item of products'>
                            <td>
                                <img *ngIf = 'showImage' [src] = 'item.imageUrl' 
                                    [title] = 'item.productName'
                                    [style.width.px]= 'imageWidth'
                                    [style.margin.px]= 'imageMargin'
                            >
                            </td>
                            <td>{{item.productName}}</td>
                            <td>{{item.productCode | lowercase}}</td>
                            <td>{{item.releaseDate}}</td>
                            <td>{{item.price | currency:'CAN':true: '1.2-2'}}</td>
                            <td>{{item.starRating}}</td>
                        </tr>

                    </tbody>
                </table>
            </div>
    </div>
</div>
2
  • dont use this productFilter:listFilter in *ngIf use it in *ngFor Commented Feb 8, 2017 at 22:52
  • you applying the pipe on wrong place. Commented Feb 8, 2017 at 23:04

2 Answers 2

1

Change this line

<table class = 'table' *ngIf='products && products.length | productFilter:listFilter'> // wrong

to this

<table class='table' *ngIf='products && products.length'> // correct

Change this line

<tr *ngFor='let item of products'>
to this
<tr *ngFor='let item of products | productFilter:listFilter'> // applying pipe here

Hope that helps.

Sign up to request clarification or add additional context in comments.

1 Comment

That was my mistake, I was filtering out the table and not the rows. Why would it through that error though? The pipe is still a sound piece of code, it was purpose wrong, so then why says filters in not a function?
1

You need to register your pipes in your App Module declaration section. make sure you included that in your app module.

@NgModule({
  declarations: [
    ProductFilterPipe
  ],
  imports: [
   ...
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Another thing, not sure you can add filter in *ngIF block. try it first outside in normal bind {{}} then put it in the ngif block if it works

1 Comment

It is included in the modules.ts file. Not sure what you mean by the Ng If blocks, I have used filters before in the same manner, I feel like the issues is in the pipe, not how I am filtering in the html

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.