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 PipeTransform interface.
  • ✔ 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