In client-side applications, we may need to filter out a set of data based on some unique values of the property passed to it. This type of data set can be a list of items with a parent-child relationship where they need to refine the child results based on parent id in it.
In Angular applications, we can do so by using Filter Pipes which can be easily used on a data object with custom login.
The Pipe Filter we are going to discuss will take a custom [key] name on which we want to filter child values. For example, there are following two data sets:
recipes = [
{
"id":1,
"name":"Burger"
},
{
"id":2,
"name":"French Fries"
},
{
"id":3,
"name":"Chowmein"
}
]
ingredients = [
{
"id":1,
"parentId":1,
"name":"Potatoes"
},
{
"id":2,
"parentId":1,
"name":"Beans"
},
{
"id":3,
"parentId":1,
"name":"Buns"
},
{
"id":4,
"parentId":1,
"name":"Carrots"
},
{
"id":5,
"parentId":2,
"name":"Cooking Oil"
},
{
"id":6,
"parentId":2,
"name":"Potatoes"
},
{
"id":7,
"parentId":2,
"name":"Pepper"
},
{
"id":8,
"parentId":2,
"name":"Salt"
},
{
"id":9,
"parentId":3,
"name":"Hakka Noodles"
},
{
"id":10,
"parentId":3,
"name":"Green Vegies"
},
{
"id":11,
"parentId":3,
"name":"Tomato Sauce"
},
{
"id":12,
"parentId":3,
"name":"Soya Souce"
}
]
If we look at the objects above, in recipes there are two properties id and name. In the ingredients object, there is a parentId property that reflects the id of recipe.
To show ingredients of a particular recipe selected, we will create a generic Angular filter pipe, where we will pass the property name on which we want to filter out ingredients which is the parentId
here.
Create a Filter Pipe
Using NG CLI tool, we can create a new Filter pipe using the generate command s shown below:
$ ng generate pipe pipes/filterParent
Above command will create a new pipe file pipes/filter-parent.pipe.ts with the following code in it:
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'filterParent'
})
export class FilterParentPipe implements PipeTransform {
transform(value: any, ...args: any[]): any {
return null;
}
}
declarations
array.// app.module.ts import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { AppComponent } from './app.component'; import { AppRoutingModule } from './app-routing.module'; import { FilterParentComponentComponent } from './components/filter-parent-component/filter-parent-component.component'; import { FilterParentPipe } from './pipes/filter-parent.pipe'; @NgModule({ declarations: [ AppComponent, FilterParentComponentComponent, FilterParentPipe ], imports: [ FormsModule, // <-- required to use [(ngModule)] in HTML component BrowserModule, AppRoutingModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
What is an Angular Pipe?
An Angular pipe is a class with @Pipe decorator which implements the PipeTransform interface. The pipe is used to format or modify the output in some required way.
The PipeTransform interface provides the transform method which can take any number of required arguments with the first one required returns the object on which we apply the filter.
Properties of @Pipe Decorator
Pipe decorator takes two properties name
(required) and pure
(optional).
The name property is the string which we will use on an object like here we have 'filterParent
'.
The pure property takes a boolean which is false by default. This property is used to enable force checking of object changes on every watch event on the component which can really adversely affect the application performance so this must be set to true only if required.
Let' move back to our filterParent
pipe.
FilterParent pipe Upgrade
In our pipe, we want to filter out the object we get in value
by the id of the recipe which we are getting in the parentId
as a transform
argument.
The keyName
is the property name of the object on which we will do filtration:
// filter-parent.pipe.ts import { Pipe, PipeTransform } from '@angular/core'; import * as _ from 'lodash'; @Pipe({ name: 'filterParent' }) export class FilterParentPipe implements PipeTransform { transform(value: string, keyName: string, parentId: any, ): string { return _.filter(value, function (o) { return o[keyName] === +parentId; }); } }
Here we are using the lodash to use its filter method.
In the above code, we are using + in front of parentId to convert it into an int to match with o[keyName] using strict comparison (===).
Usage of Filter in Template
Usage of this pipe is very simple, just add it using a pipe operator as shown below with a property name and second argument as the id of recipe selected in the select box:
<h5>Select Recipe</h5> <select name="recipes" [(ngModel)]="recipeModel"> <option [value]="r.id" *ngFor="let r of recipes">{{r.name}}</option> </select> <h5>Ingredients</h5> <ul> <li *ngFor="let ing of ingredients | filterParent:'parentId':recipeModel"> {{ing.name}} </li> </ul>
In the above code, we have used pipe on ingredients object.
That's it so here we got to know how to create a filter pipe in Angular to filter out child objects using a parent id or by any property passed to filter.