Angular Custom Pipes
Master Angular Custom Pipes with step-by-step examples, PipeTransform, standalone pipes, parameterized pipes, pure vs impure pipes, dependency injection, performance optimization, architecture diagrams, enterprise use cases, and interview questions.
Angular provides many built-in pipes like date, currency, and uppercase. However, enterprise applications often require custom data transformations that are specific to business requirements.
Examples include:
- Masking account numbers
- Formatting employee IDs
- Converting status codes
- Formatting phone numbers
- Capitalizing product names
- Displaying customer initials
- Converting file sizes
- Formatting transaction references
Angular allows developers to create Custom Pipes that encapsulate reusable transformation logic.
Custom Pipes are commonly used in enterprise Angular applications and are frequently discussed during Angular interviews.
Table of Contents
- What are Custom Pipes?
- Why Use Custom Pipes?
- PipeTransform Interface
- Creating a Custom Pipe
- Standalone Pipes
- Parameterized Pipes
- Chaining Pipes
- Pure vs Impure Pipes
- Dependency Injection in Pipes
- Enterprise Examples
- Performance Best Practices
- Top 10 Interview Questions
- Summary
What are Custom Pipes?
A Custom Pipe transforms application data into a format suitable for presentation.
Instead of writing formatting logic repeatedly in components or templates, Angular encourages placing reusable formatting logic inside custom pipes.
Custom Pipe Architecture
flowchart LR
Component
Component --> CustomPipe
CustomPipe --> TransformedData
TransformedData --> Template
Template --> Browser
Why Use Custom Pipes?
Without Custom Pipes
- Duplicate formatting logic
- Large components
- Difficult maintenance
- Less reusable code
With Custom Pipes
- Centralized formatting
- Better readability
- Reusable transformations
- Easier testing
- Better separation of concerns
Pipe Transformation Flow
sequenceDiagram
participant Component
participant CustomPipe
participant Template
participant Browser
Component->>CustomPipe: Raw Data
CustomPipe->>Template: Formatted Data
Template-->>Browser: Display Result
Creating Your First Custom Pipe
Generate using Angular CLI
ng generate pipe reverse
or
ng g p reverse
Pipe Structure
reverse.pipe.ts
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'reverse',
standalone: true
})
export class ReversePipe implements PipeTransform {
transform(value: string): string {
return value.split('').reverse().join('');
}
}
Using the Pipe
Component
name = "Angular";
Template
{{ name | reverse }}
Output
ralugnA
How Angular Executes a Pipe
flowchart TD
A[Component]
B[Reverse Pipe]
C["transform()"]
D[Template]
E[Browser]
A --> B
B --> C
C --> D
D --> E
PipeTransform Interface
Every custom pipe implements the PipeTransform interface.
interface PipeTransform {
transform(
value:any,
...args:any[]
):any;
}
The transform() method receives:
- Input value
- Optional parameters
and returns the transformed value.
Parameterized Custom Pipe
Example
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'truncate',
standalone: true
})
export class TruncatePipe implements PipeTransform {
transform(value: string, length: number): string {
if (!value) {
return '';
}
return value.length > length
? value.substring(0, length) + '...'
: value;
}
}
Usage
{{ description | truncate:20 }}
Output
Angular is a...
Multiple Parameters
transform(
value:string,
length:number,
suffix:string
){
return value.substring(0,length)+suffix;
}
Usage
{{ title | truncate:15:'...' }}
Pipe Execution Flow
flowchart LR
Input
Input --> TransformMethod
TransformMethod --> Output
Output --> Browser
Chaining Custom Pipes
Pipes can be chained together.
{{ username | uppercase | reverse }}
Execution
Angular
↓
UPPERCASE
↓
REVERSE
↓
RALUGNA
Standalone Pipes
Angular supports standalone pipes.
@Pipe({
name: 'capitalize',
standalone: true
})
export class CapitalizePipe
implements PipeTransform {
transform(value:string){
return value.charAt(0).toUpperCase()
+ value.slice(1);
}
}
Import into a standalone component.
@Component({
standalone: true,
imports: [CapitalizePipe]
})
export class UserComponent {}
Pure Pipes
Default behavior.
@Pipe({
name:'salary'
})
Characteristics
- Runs when the input reference changes
- Better performance
- Recommended for most applications
Impure Pipes
@Pipe({
name:'salary',
pure:false
})
Characteristics
- Executes during every change detection cycle
- Useful only for special scenarios
- May negatively impact performance
Pure vs Impure Architecture
flowchart TD
ChangeDetection
ChangeDetection --> PurePipe
ChangeDetection --> ImpurePipe
PurePipe --> ReferenceChanged
ReferenceChanged --> Render
ImpurePipe --> EveryCycle
EveryCycle --> Render
Dependency Injection in Pipes
Custom Pipes can inject Angular services.
Example
import { Pipe, PipeTransform } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class MaskService {
mask(value: string): string {
return value.replace(/\d(?=\d{4})/g, '*');
}
}
@Pipe({
name: 'maskAccount',
standalone: true
})
export class MaskAccountPipe
implements PipeTransform {
constructor(
private maskService: MaskService
) {}
transform(value: string): string {
return this.maskService.mask(value);
}
}
Template
{{ accountNumber | maskAccount }}
Output
********1234
Enterprise Banking Example
Account Number
1234567890123456
Display
************3456
Implementation
{{ account.number | maskAccount }}
Enterprise Dashboard
flowchart TD
RESTAPI
RESTAPI --> AccountComponent
AccountComponent --> CurrencyPipe
AccountComponent --> DatePipe
AccountComponent --> MaskAccountPipe
CurrencyPipe --> Dashboard
DatePipe --> Dashboard
MaskAccountPipe --> Dashboard
File Size Pipe Example
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'fileSize',
standalone: true
})
export class FileSizePipe
implements PipeTransform {
transform(bytes:number):string{
if(bytes < 1024){
return bytes + ' B';
}
if(bytes < 1024 * 1024){
return (bytes/1024).toFixed(2) + ' KB';
}
return (bytes/(1024*1024)).toFixed(2) + ' MB';
}
}
Usage
{{ file.size | fileSize }}
Output
2.45 MB
Status Pipe Example
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'statusText',
standalone: true
})
export class StatusTextPipe
implements PipeTransform {
transform(status:number):string{
switch(status){
case 1:
return 'Pending';
case 2:
return 'Approved';
case 3:
return 'Rejected';
default:
return 'Unknown';
}
}
}
Usage
{{ loan.status | statusText }}
Performance Best Practices
| Practice | Benefit |
|---|---|
| Prefer Pure Pipes | Better rendering performance |
| Keep Pipes Stateless | Easier maintenance |
| Avoid Heavy Calculations | Faster UI |
| Avoid HTTP Calls | Pipes should be presentation-focused |
| Prefer Services for Business Logic | Cleaner architecture |
| Use Standalone Pipes | Simpler imports |
Common Mistakes
Business Logic Inside Pipes
❌ Avoid
transform(){
// Loan approval logic
}
Business rules belong in services, not pipes.
API Calls
❌ Never
http.get(...)
inside a pipe.
Pipes should not make network requests.
Database Operations
Avoid performing database operations or expensive computations inside pipes.
Using Impure Pipes Unnecessarily
Impure pipes run during every change detection cycle and should only be used when truly required.
Advantages
| Feature | Benefit |
|---|---|
| Reusable | Write once, use everywhere |
| Readable | Cleaner templates |
| Standalone | Simple imports |
| Testable | Easy unit testing |
| Maintainable | Separation of concerns |
| Flexible | Supports parameters |
Real-World Enterprise Use Cases
| Scenario | Custom Pipe |
|---|---|
| Banking | Account Number Mask |
| Insurance | Policy Number Formatter |
| HR | Employee ID Formatter |
| E-Commerce | Product Code Formatter |
| Healthcare | Patient ID Mask |
| Logistics | Tracking Number Formatter |
| Telecom | Phone Number Formatter |
| Cloud | File Size Formatter |
Top 10 Angular Custom Pipes Interview Questions
1. What is a Custom Pipe?
Answer
A Custom Pipe transforms application data into a presentation-friendly format using developer-defined transformation logic.
2. Which interface must every Custom Pipe implement?
Answer
PipeTransform
3. What is the purpose of the transform() method?
Answer
It receives the input value and optional parameters, performs the transformation, and returns the formatted result.
4. Can a Custom Pipe accept parameters?
Answer
Yes.
Example
{{ description | truncate:20 }}
5. What is the difference between Pure and Impure Pipes?
| Pure Pipe | Impure Pipe |
|---|---|
| Executes when input reference changes | Executes during every change detection cycle |
| Better performance | Slower |
| Default | pure:false |
6. Can multiple pipes be chained?
Answer
Yes.
{{ name | uppercase | reverse }}
7. Can Angular services be injected into a Pipe?
Answer
Yes. Dependency Injection is supported, allowing reusable helper services such as masking or formatting utilities.
8. Are Standalone Pipes supported?
Answer
Yes. Standalone Pipes can be imported directly into standalone components without NgModules.
9. Should HTTP calls be made inside a Pipe?
Answer
No. Pipes should remain focused on presentation logic. Data retrieval belongs in services.
10. What are the best practices for Custom Pipes?
Answer
- Keep pipes small and reusable.
- Prefer Pure Pipes.
- Avoid business logic.
- Avoid HTTP calls.
- Use parameters for flexibility.
- Create Standalone Pipes for modern Angular applications.
- Write unit tests for custom pipes.
Interview Cheat Sheet
| Topic | Remember |
|---|---|
| Interface | PipeTransform |
| Main Method | transform() |
| Pipe Syntax | {{ value | pipe }} |
| Parameters | pipe:param |
| Multiple Parameters | pipe:p1:p2 |
| Default Type | Pure |
| Standalone | Supported |
| Dependency Injection | Supported |
| Async Work | Use Services, not Pipes |
| Best Practice | Keep Pipes Stateless |
Summary
Custom Pipes provide a clean and reusable way to encapsulate presentation-specific transformations in Angular applications. By implementing the PipeTransform interface, developers can build reusable formatting utilities such as account masking, file size conversion, status mapping, and string formatting. Modern Angular applications benefit from Standalone Pipes, dependency injection, and Pure Pipes to create scalable, maintainable, and high-performance user interfaces.
Key Takeaways
- ✔ Custom Pipes encapsulate reusable presentation logic.
- ✔ Implement the
PipeTransforminterface. - ✔ Use the
transform()method for data conversion. - ✔ Support parameters for flexible transformations.
- ✔ Prefer Pure Pipes for better performance.
- ✔ Use Standalone Pipes in Angular 15+ applications.
- ✔ Dependency Injection is supported.
- ✔ Avoid business logic and HTTP calls inside pipes.
- ✔ Keep pipes stateless whenever possible.
- ✔ Custom Pipes are a common Angular interview topic.
Next Article
➡️ 28-Template-Driven-Forms-QA.md