Introduction
Angular provides a powerful feature known as pipes, which are used to transform data before displaying it in templates. They allow developers to format values directly within the HTML template, keeping components clean and focused only on logic.
Sometimes, a single transformation is not enough. You may need to apply multiple transformations sequentially — for example, converting text to uppercase and then slicing a part of it, or formatting a date before localizing it.
This is where chaining multiple pipes becomes useful.
By chaining pipes, Angular applies them from left to right, passing the transformed output of one pipe as the input to the next. This approach leads to more readable, maintainable, and concise templates.
This post provides an in-depth exploration of how to chain multiple pipes in Angular effectively, with examples, use cases, and performance insights.
Table of Contents
- What Are Pipes in Angular
- Why Use Multiple Pipes
- Understanding Pipe Chaining
- Syntax for Chaining Pipes
- How Pipe Chaining Works Internally
- Simple Example of Chained Pipes
- Chaining Pipes with Parameters
- Example: Formatting a String with Uppercase and Slice
- Example: Formatting Numbers with Multiple Pipes
- Example: Formatting Dates with Multiple Pipes
- Using Custom Pipes in a Chain
- Combining Built-in and Custom Pipes
- Using AsyncPipe with Other Pipes
- Applying Chained Pipes in Structural Directives
- Using Pipes with Interpolation and Property Binding
- Chaining Pipes in Tables and Lists
- Handling Null or Undefined Values
- Safe Navigation Operator with Pipe Chains
- Performance Implications of Multiple Pipes
- Pure vs Impure Pipes in Chaining
- Common Mistakes in Pipe Chaining
- Conditional Chaining in Templates
- Dynamic Data Transformation with Chained Pipes
- Using Pipes for Localization
- Creating Reusable Pipe Combinations
- Example: Full Name and Initials Formatter
- Example: Filtering and Displaying Lists
- Testing Pipe Chains in Unit Tests
- Best Practices for Chaining Pipes
- Conclusion
1. What Are Pipes in Angular
Pipes are special functions that take input data and return transformed output data.
They are used directly in templates with the pipe (|
) symbol.
Example:
<p>{{ username | uppercase }}</p>
If username
is "john doe"
, the output will be:
JOHN DOE
2. Why Use Multiple Pipes
Sometimes, you may want to apply multiple transformations sequentially.
Instead of performing these transformations in the component TypeScript code, you can use chained pipes to make templates cleaner.
For example:
- Convert text to uppercase, then display only part of it.
- Format a number and then append a currency symbol.
- Format a date, then adjust it to a specific locale.
- Combine filters for lists dynamically.
3. Understanding Pipe Chaining
Pipe chaining means applying more than one pipe to the same expression.
The output of the first pipe becomes the input of the next pipe in the chain.
For example:
{{ value | pipe1 | pipe2 }}
Angular evaluates this as:
pipe2(pipe1(value))
4. Syntax for Chaining Pipes
The syntax is simple:
{{ value | firstPipe | secondPipe:arg1:arg2 | thirdPipe }}
Each pipe is separated by the |
character.
Arguments can be passed to any pipe in the chain.
5. How Pipe Chaining Works Internally
When Angular encounters a pipe chain, it processes it from left to right.
For example:
{{ data | pipeA | pipeB }}
Angular executes it internally as:
pipeB.transform(pipeA.transform(data))
This means the result of pipeA
becomes the input to pipeB
.
6. Simple Example of Chained Pipes
<p>{{ 'hello world' | uppercase | slice:0:5 }}</p>
Steps:
uppercase
→ converts'hello world'
to'HELLO WORLD'
slice:0:5
→ extracts the first 5 characters
Output:
HELLO
7. Chaining Pipes with Parameters
You can pass parameters to any pipe in the chain independently.
Example:
<p>{{ price | number:'1.2-2' | currency:'USD' }}</p>
Steps:
number:'1.2-2'
formats the number with two decimal places.currency:'USD'
converts it to a currency format.
Output Example:
$1,234.56
8. Example: Formatting a String with Uppercase and Slice
Component:
user = { name: 'Alexander Hamilton' };
Template:
<p>{{ user.name | uppercase | slice:0:10 }}</p>
Steps:
- Converts name to uppercase →
ALEXANDER HAMILTON
- Slices to first 10 characters →
ALEXANDER
Output:
ALEXANDER
9. Example: Formatting Numbers with Multiple Pipes
<p>{{ 1234.56789 | number:'1.2-2' | currency:'USD' }}</p>
- The
number
pipe limits decimal places. - The
currency
pipe converts to a currency format.
Output:
$1,234.57
10. Example: Formatting Dates with Multiple Pipes
<p>{{ today | date:'fullDate' | uppercase }}</p>
If today is October 9, 2025
, output will be:
THURSDAY, OCTOBER 9, 2025
11. Using Custom Pipes in a Chain
You can combine custom pipes with Angular’s built-in ones.
Example custom pipe:
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({ name: 'exclaim' })
export class ExclaimPipe implements PipeTransform {
transform(value: string): string {
return value + '!';
}
}
Template:
<p>{{ 'angular pipes' | uppercase | exclaim }}</p>
Output:
ANGULAR PIPES!
12. Combining Built-in and Custom Pipes
You can mix and match both types seamlessly:
<p>{{ message | lowercase | titlecase | exclaim }}</p>
If message
= "HELLO FROM ANGULAR"
,
Output:
Hello From Angular!
13. Using AsyncPipe with Other Pipes
When working with Observables, you can chain async
with other pipes.
Example:
<p>{{ userService.getUserName() | async | uppercase }}</p>
Steps:
async
subscribes to the Observable and retrieves its emitted value.uppercase
converts that emitted value to uppercase.
14. Applying Chained Pipes in Structural Directives
You can also use chained pipes inside directives like *ngFor
.
<li *ngFor="let item of items | slice:0:5 | orderBy:'name'">
{{ item.name | titlecase }}
</li>
Here:
- The list is sliced to first 5 items.
- Then sorted.
- Each name is capitalized.
15. Using Pipes with Interpolation and Property Binding
You can use chained pipes inside both interpolation and property bindings.
<p>{{ dateValue | date:'shortDate' | uppercase }}</p>
<input [value]="user.name | uppercase | slice:0:8" />
16. Chaining Pipes in Tables and Lists
Chained pipes are frequently used in tables:
<tr *ngFor="let order of orders">
<td>{{ order.id }}</td>
<td>{{ order.date | date:'mediumDate' | uppercase }}</td>
<td>{{ order.total | currency:'USD' | slice:0:8 }}</td>
</tr>
This improves readability and consistent formatting across columns.
17. Handling Null or Undefined Values
If data might be undefined, you can use conditional chaining with pipes:
<p>{{ user?.name | uppercase | slice:0:10 }}</p>
This prevents runtime errors when user
is null.
18. Safe Navigation Operator with Pipe Chains
Angular allows combining the safe navigation operator (?.
) with pipes:
<p>{{ product?.title | lowercase | slice:0:15 }}</p>
If product
is not yet loaded, Angular safely skips evaluation until it exists.
19. Performance Implications of Multiple Pipes
Every pipe transformation adds a computation layer during change detection.
Angular optimizes performance for pure pipes, which only re-run when the input changes.
Best Practice:
- Prefer pure pipes.
- Avoid chaining impure pipes unnecessarily.
- For heavy data transformations, move logic to component code or services.
20. Pure vs Impure Pipes in Chaining
- Pure Pipes: Run only when the input value changes.
Example:uppercase
,slice
,date
,currency
. - Impure Pipes: Run on every change detection cycle.
Example: Pipes that mutate arrays or depend on external state.
Avoid chaining impure pipes with others unless necessary.
21. Common Mistakes in Pipe Chaining
- Using wrong order of pipes (e.g., slicing before formatting).
- Forgetting to handle null values.
- Passing incorrect arguments.
- Expecting async data before using async pipe.
- Overusing multiple impure pipes causing performance issues.
22. Conditional Chaining in Templates
You can apply pipes conditionally using ternary operators:
<p>{{ isUpper ? (text | uppercase | slice:0:10) : (text | lowercase) }}</p>
23. Dynamic Data Transformation with Chained Pipes
<p>{{ dynamicText | titlecase | slice:0:20 | lowercase }}</p>
Each pipe modifies the text step-by-step, giving full control over how data appears.
24. Using Pipes for Localization
Pipes can be chained to localize data dynamically.
<p>{{ today | date:'fullDate' | lowercase }}</p>
<p>{{ today | date:'fullDate':'':'fr' | uppercase }}</p>
This allows combining formatting with language-specific presentation.
25. Creating Reusable Pipe Combinations
Instead of repeating the same chain, you can create a custom pipe that internally combines transformations.
@Pipe({ name: 'shortUpper' })
export class ShortUpperPipe implements PipeTransform {
transform(value: string): string {
return value.toUpperCase().slice(0, 8);
}
}
Then use it like:
<p>{{ user.name | shortUpper }}</p>
26. Example: Full Name and Initials Formatter
@Pipe({ name: 'initials' })
export class InitialsPipe implements PipeTransform {
transform(fullName: string): string {
const parts = fullName.split(' ');
return parts.map(p => p[0].toUpperCase()).join('');
}
}
Template:
<p>{{ user.fullName | initials | slice:0:3 }}</p>
If fullName = "John Alexander Smith"
,
Output: JAS
27. Example: Filtering and Displaying Lists
<li *ngFor="let product of products | filter:'available' | slice:0:5">
{{ product.name | titlecase }}
</li>
This filters available products and limits the display to the first five.
28. Testing Pipe Chains in Unit Tests
You can test pipe chaining behavior using unit tests.
import { UpperCasePipe, SlicePipe } from '@angular/common';
describe('Pipe Chaining', () => {
it('should uppercase and slice text correctly', () => {
const upper = new UpperCasePipe();
const slice = new SlicePipe();
const result = slice.transform(upper.transform('angular chaining'), 0, 7);
expect(result).toBe('ANGULAR');
});
});
29. Best Practices for Chaining Pipes
- Keep pipe chains short and meaningful.
- Avoid mixing impure and pure pipes unnecessarily.
- Handle
null
andundefined
values with safe navigation. - Use custom combined pipes for repetitive chains.
- Use async pipe last in a chain.
- Ensure arguments are correct and consistent.
- Prefer chaining for simple formatting, not complex logic.
- Avoid chaining in performance-critical sections like large lists.
Leave a Reply