Search code examples
angularangular-pipe

What causes the failure to use an Angular custom pipe in a component?


I have been working on an e-commerce app in Angular 14.

I have a list of products that I want to filter by brand and, for this purpose, I have mede the following custom pipe (app/pipes/filter-products.pipe.ts):

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

@Pipe({
  name: 'filterProductsByBrand',
})
export class FilterProductsPipe implements PipeTransform {
  transform(input: Product[], brand?: String): any {
    let output: Product[] = [];
    if (brand == '') output = input;
    else output = input.filter((item) => item.brand == brand);
    return output;
  }
}

I have imported the pipe in app.modules.ts and added it to the declarations arary.

In the products-list.component.ts file I have:

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { Product, ProductResponse } from '../../models/product';
import { ProductService } from '../../services/product.service';

@Component({
  selector: 'app-products-list',
  templateUrl: './products-list.component.html',
  styleUrls: ['./products-list.component.css'],
})
export class ProductsListComponent implements OnInit {
  selectedBrand: String = '';
  productResponse!: ProductResponse;
  products: Product[];

  constructor(private ProductService: ProductService, private Router: Router) {}

  ngOnInit(): void {
    this.getPoducts();
  }

  public getPoducts() {
    this.ProductService.getProducts().subscribe((response) => {
      this.productResponse = response;
      this.products = this.productResponse.products;
    });
  }
}

In the above component's template:

<div class="mb-3">
  <select
    [(ngModel)]="selectedBrand"
    (change)="getPoducts()"
    class="form-select"
  >
    >
    <option selected value="">All brands</option>
    <option value="Apple">Apple</option>
    <option value="Samsung">Samsung</option>
  </select>
</div>

<!-- Card list Begin -->
<ng-container *ngIf="productResponse">
  <div class="row">
    <div
      *ngFor="let product of products | filter: filterProductsByBrand"
      class="product col-sm-6 col-md-4"
    >
      <app-product-item [product]="product"></app-product-item>
    </div>
  </div> </ng-container
><!-- Card list End -->

The problem

The code fails to compile and I get the error:

Property 'filterProductsByBrand' does not exist on type 'ProductsListComponent'.

Stackblitz

I have put toghteter this stackblitz.

Questions

  1. What am I doing wrong?
  2. What is the most reliable way to fix this issue?

Solution

  • <div *ngFor="let product of products | filter: filterProductsByBrand">
    

    The selector for your pipe is filterProductsByBrand but here you are trying to use a pipe called filter and passing the string "filterProductsByBrand" as a second argument.

    Try <div *ngFor="let product of products | filterProductsByBrand: 'brand-name'">