Custom Filter Pipe
Create your own custom pipe — build a filter pipe that searches and filters list items in real time.
Custom Filter Pipe
Angular's built-in pipes are great, but you can create custom pipes for your specific data transformation needs. Let's build a filter pipe that searches through a list.
Generate a Pipe with the CLI
ng generate pipe filter
# or
ng g p filter
The Generated Pipe
// filter.pipe.ts
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'filter'
})
export class FilterPipe implements PipeTransform {
transform(value: unknown, ...args: unknown[]): unknown {
return null;
}
}
Building the Filter Pipe
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'filter'
})
export class FilterPipe implements PipeTransform {
transform(items: any[], searchTerm: string, property: string): any[] {
// Return all items if no search term
if (!items || !searchTerm) {
return items;
}
// Filter items where the property contains the search term
const lowerSearch = searchTerm.toLowerCase();
return items.filter(item => {
return item[property].toLowerCase().includes(lowerSearch);
});
}
}
Using the Filter Pipe
// component
export class UserListComponent {
searchTerm = '';
users = [
{ name: 'Alice Johnson', role: 'Admin' },
{ name: 'Bob Smith', role: 'Developer' },
{ name: 'Carol Williams', role: 'Designer' },
{ name: 'David Brown', role: 'Developer' },
{ name: 'Eve Davis', role: 'Manager' },
];
}
// template
<input [(ngModel)]="searchTerm" placeholder="Search users...">
<div *ngFor="let user of users | filter:searchTerm:'name'">
<h3>{{ user.name }}</h3>
<p>{{ user.role }}</p>
</div>
<p *ngIf="(users | filter:searchTerm:'name').length === 0">
No users found matching "{{ searchTerm }}"
</p>
Multi-Property Search
@Pipe({ name: 'search' })
export class SearchPipe implements PipeTransform {
transform(items: any[], searchTerm: string, properties: string[]): any[] {
if (!items || !searchTerm) return items;
const lower = searchTerm.toLowerCase();
return items.filter(item => {
return properties.some(prop =>
item[prop]?.toString().toLowerCase().includes(lower)
);
});
}
}
// template — search across name AND role:
<div *ngFor="let user of users | search:searchTerm:['name','role']">
{{ user.name }} — {{ user.role }}
</div>
Custom Formatting Pipe
@Pipe({ name: 'truncate' })
export class TruncatePipe implements PipeTransform {
transform(value: string, limit: number = 50, trail: string = '...'): string {
if (!value) return '';
if (value.length <= limit) return value;
return value.substring(0, limit) + trail;
}
}
// template
<p>{{ longText | truncate:100 }}</p>
<p>{{ description | truncate:50:'…' }}</p>
Registering the Pipe
// app.module.ts
@NgModule({
declarations: [
AppComponent,
FilterPipe, // Register here
TruncatePipe,
],
// ...
})
The CLI does this automatically when using ng g p.
Pure vs Impure Pipes
| Type | When It Runs | Performance |
|---|---|---|
| Pure (default) | Only when input value changes | Fast — cached |
| Impure | On every change detection cycle | Slower — runs constantly |
@Pipe({
name: 'filter',
pure: false // Makes it impure — runs on every change detection
})
Key Takeaways
- Create custom pipes with
ng g p pipe-name - Implement the
PipeTransforminterface with atransform()method - Use pipes in templates:
{{ data | pipeName:arg1:arg2 }} - Pipes are pure by default — they only re-run when inputs change
- Custom pipes are perfect for filtering, formatting, and transforming data