andrey.shedko
andrey.shedko

Reputation: 3238

Custom pipe is not working

I did implement custom pipe that getting array of objects and then filter this array accroding to user input. But if I'm using element reference instead of [(ngModel)], it's not working.
Here is input element and pipe:

<input class="form-control ml-1" type="text" placeholder="Найти запчасть по названию" #search>

...

<tr *ngFor="let item of currentModel | searchPipe: search.value">

And here is pipe itself.

@Pipe({
  name: 'searchPipe'
})
export class SearchPipe implements PipeTransform {

  transform(value: CatalogueShortDto[], args?: any): any {
    if (!isNullOrUndefined(args) && args.length > 0) {
      return value.filter(search => {
        return search.bluePrintCode.includes(args) || search.sparePartName.includes(args);
      });
    } else {
      return value;
    }
  }
}

Even breakpoints in pipe wasn't fired. Any ideas?

Upvotes: 1

Views: 922

Answers (2)

DeborahK
DeborahK

Reputation: 60596

Filtering in code ... Just bind to filteredProducts.

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

import { IProduct } from './product';
import { ProductService } from './product.service';

@Component({
    templateUrl: './product-list.component.html'
})
export class ProductListComponent implements OnInit {

    _listFilter: string;
    get listFilter(): string {
        return this._listFilter;
    }
    set listFilter(value: string) {
        this._listFilter = value;
        this.filteredProducts = this.listFilter ? this.performFilter(this.listFilter) : this.products;
    }

    errorMessage: string;
    filteredProducts: IProduct[];
    products: IProduct[] = [];

    constructor(private _productService: ProductService) {

    }

    performFilter(filterBy: string): IProduct[] {
        filterBy = filterBy.toLocaleLowerCase();
        return this.products.filter((product: IProduct) =>
              product.productName.toLocaleLowerCase().indexOf(filterBy) !== -1);
    }

    ngOnInit(): void {
        this._productService.getProducts()
                .subscribe(products => {
                    this.products = products;
                    this.filteredProducts = this.products;
                },
                    error => this.errorMessage = <any>error);
    }
}

Upvotes: 1

yurzui
yurzui

Reputation: 214295

According to the docs https://angular.io/guide/user-input#get-user-input-from-a-template-reference-variable

Angular updates the bindings (and therefore the screen) only if the app does something in response to asynchronous events, such as keystrokes. This example code binds the keyup event to the number 0, the shortest template statement possible. While the statement does nothing useful, it satisfies Angular's requirement so that Angular will update the screen.

So you can use either

<input (input)="0"

or

<input (keyup)="0"

Plunker Example

Upvotes: 0

Related Questions