javaland235
javaland235

Reputation: 803

Angular Custom Pipe for filtering Arrays

I have an array of Requirement objects and array of product objects. Every requirement has one to many relationship with products i.e. one requirement has multiple products. every product object has a requirement object in it and from this requirement object we can find out which requirement it belongs to by accessing requirement.id value.

Now I have this HTML template

<div class="row" *ngFor="let requirement of requirements; let i= index">
  <div class="col-md-12" style="margin-bottom: 15px;">
    <h3 style="display: inline">{{requirement.title}}</h3>

    <table class="table table-bordered table-hover">
      <tr>
        <th>Product Name</th>
        <th>Unit Cost</th>
        <th>Qty</th>
        <th>Unit</th>
        <th>Total Cost</th>
        <th>Product Profit</th>
        <th>Product VAT</th>
        <th>Total Price</th>
      </tr>
      <tr *ngFor="let product of products | productFilter: requirement">
        <td>{{product.name}}</td>
        <td>{{product.unitCost}}</td>
        <td>{{product.qty}}</td>
        <td>{{product.unit}}</td>
        <td>{{product.totalCost | number:'.'}}</td>
        <td>{{product.profit | number:'.'}}</td>
        <td>{{product.vat | number:'.'}}</td>
        <td>{{product.totalPrice | number:'.'}}</td>
      </tr>
      <tr>
        <td colspan="7"><strong>Sub-Total</strong></td>
        <td><strong>{{requirement.requirementTotal}}</strong></td>
      </tr>
    </table>
  </div>
</div>

The template loops through every requirement and then it fills up the products table for each requirement. I am using a custom pipe to filter the products for each requirement.

Here is the code for my custom pipe

@Pipe({
  name: 'productFilter'
})
export class ProductFilterPipe implements PipeTransform {
  transform(products: Product[], requirement: Requirement): Product[] {
    const filteredProducts = products.filter(product => product.requirement.id === requirement.id);
    return filteredProducts;
  }
}

But it is not giving me the intended result. I have two requirements in the requirements array and 4 products in the products array. each requirement has 2 products. But each time I load the page, only 2 products from any one requirement get displayed while other two products don't show up in the table.

Please note that previously I got my intended result using *ngIf on each <td> element of my table using the below code

<td *ngIf = "product.requirement.id===requirement.id">{{product.name}}</td> 

How can I solve this issue. Please help

Upvotes: 2

Views: 962

Answers (1)

Arne
Arne

Reputation: 842

Why wouldn't you just use an *ngIf on the tr and be done? I'd honestly solve it by presorting the data using a map, but I see no reason why a single *ngIf on the tr wouldn't work.

Anyhow, your pipe doesn't work because you for your purpose would need an impure pipe, and you explicitly have to identify the pipe as such. See https://angular.io/guide/pipes#pure-and-impure-pipes

Upvotes: 1

Related Questions