In Angular, pipes are a powerful feature that allow you to transform data directly in your templates. They make your HTML cleaner, your components simpler, and your application more readable. Instead of formatting data manually in the component, you can use pipes to format data on the fly.
Angular comes with several built-in pipes that handle the most common transformations such as formatting dates, numbers, currencies, and percentages, and even working with asynchronous data streams.
This post will cover everything you need to know about built-in pipes in Angular, including:
- What pipes are and why they’re useful
- How to use built-in pipes
- Detailed explanation of common built-in pipes
- Syntax, parameters, and examples for each pipe
- Best practices when using pipes
- Performance and async data handling with
AsyncPipe
- Combining multiple pipes in templates
- Common pitfalls and troubleshooting
- Real-world examples
1. What Are Pipes in Angular?
A pipe is a way to transform data within Angular templates. You can think of it as a data formatting function that runs automatically inside the template expression.
The syntax for using a pipe is simple:
{{ value | pipeName }}
You can also pass arguments to pipes:
{{ value | pipeName:argument1:argument2 }}
Angular processes the expression on the left, sends it through the pipe, and displays the transformed output in the DOM.
2. Why Use Pipes?
Without pipes, you might need to manually format values in your component TypeScript code. Pipes allow you to:
- Keep templates clean and expressive.
- Avoid repetitive logic for common transformations.
- Use built-in data formatting tools instead of writing them manually.
- Improve maintainability and readability.
Example without pipes:
export class ExampleComponent {
currentDate = new Date();
getFormattedDate(): string {
return this.currentDate.toDateString();
}
}
In the template:
<p>{{ getFormattedDate() }}</p>
Example with pipes:
<p>{{ currentDate | date:'fullDate' }}</p>
Cleaner, faster, and declarative.
3. Using Built-in Pipes in Angular
Angular provides many built-in pipes out of the box. The most commonly used include:
- DatePipe – formats date values.
- CurrencyPipe – formats numbers as currency.
- DecimalPipe – formats decimal numbers.
- PercentPipe – formats numbers as percentages.
- AsyncPipe – handles asynchronous data like Observables or Promises.
To use any pipe, simply reference it in the template expression using the pipe |
character.
4. DatePipe
The DatePipe
is one of the most commonly used built-in pipes in Angular. It formats date values according to locale rules or custom formats.
Syntax
{{ dateValue | date[:format[:timezone[:locale]]] }}
Example
export class DateExampleComponent {
today: Date = new Date();
}
Template:
<p>Default: {{ today | date }}</p>
<p>Full date: {{ today | date:'fullDate' }}</p>
<p>Short date: {{ today | date:'shortDate' }}</p>
<p>Custom: {{ today | date:'dd/MM/yyyy, h:mm a' }}</p>
Output Example
Default: Oct 9, 2025
Full date: Thursday, October 9, 2025
Short date: 10/9/25
Custom: 09/10/2025, 9:15 AM
Common Format Options
Format | Example Output |
---|---|
'short' | 10/9/25, 9:15 AM |
'medium' | Oct 9, 2025, 9:15:00 AM |
'long' | October 9, 2025 at 9:15:00 AM GMT+5 |
'fullDate' | Thursday, October 9, 2025 |
'shortDate' | 10/9/25 |
'dd/MM/yyyy' | 09/10/2025 |
You can also use time zones and locale settings if your app supports multiple languages or regions.
5. CurrencyPipe
The CurrencyPipe
is used to format numeric values as currency strings. It automatically adds currency symbols and formats numbers according to locale.
Syntax
{{ amount | currency[:currencyCode[:display[:digitsInfo[:locale]]]] }}
Example
export class CurrencyExampleComponent {
price = 3499.99;
}
Template:
<p>Default (USD): {{ price | currency }}</p>
<p>Euro: {{ price | currency:'EUR' }}</p>
<p>GBP Symbol: {{ price | currency:'GBP':'symbol':'1.2-2' }}</p>
<p>Code Format: {{ price | currency:'USD':'code' }}</p>
<p>Custom Locale: {{ price | currency:'INR':'symbol':'1.0-0':'en-IN' }}</p>
Output Example
Default (USD): $3,499.99
Euro: €3,499.99
GBP Symbol: £3,499.99
Code Format: USD3,499.99
Custom Locale: ₹3,500
Explanation of Parameters
- currencyCode: The ISO code (e.g., ‘USD’, ‘EUR’, ‘INR’).
- display: Can be
'symbol'
,'code'
, or'symbol-narrow'
. - digitsInfo: Format string like
'1.2-2'
where:1
→ minimum integer digits2
→ minimum fraction digits2
→ maximum fraction digits
- locale: Adjusts output format for language and region.
6. DecimalPipe
The DecimalPipe
formats a number as a decimal according to locale rules.
Syntax
{{ numberValue | number[:digitsInfo[:locale]] }}
Example
export class DecimalExampleComponent {
num1 = 1234.5;
num2 = 9876543.21;
}
Template:
<p>Default: {{ num1 | number }}</p>
<p>Custom format (1.0-0): {{ num1 | number:'1.0-0' }}</p>
<p>Two decimals (1.2-2): {{ num2 | number:'1.2-2' }}</p>
<p>Indian Locale: {{ num2 | number:'1.2-2':'en-IN' }}</p>
Output Example
Default: 1,234.5
Custom format: 1,235
Two decimals: 9,876,543.21
Indian Locale: 98,76,543.21
This pipe is useful for displaying calculated or statistical data consistently across your app.
7. PercentPipe
The PercentPipe
formats a numeric value as a percentage string.
Syntax
{{ value | percent[:digitsInfo[:locale]] }}
Example
export class PercentExampleComponent {
completion = 0.8532;
rate = 0.125;
}
Template:
<p>Default: {{ completion | percent }}</p>
<p>One decimal: {{ completion | percent:'1.1-1' }}</p>
<p>Two decimals: {{ rate | percent:'1.2-2' }}</p>
Output Example
Default: 85%
One decimal: 85.3%
Two decimals: 12.50%
By default, Angular multiplies the number by 100 and adds the percent symbol.
8. AsyncPipe
The AsyncPipe
is one of the most powerful and unique pipes in Angular. It automatically subscribes to an Observable or Promise and returns the latest value emitted. It also handles unsubscription automatically to avoid memory leaks.
Syntax
{{ observableValue | async }}
Example Using Observable
import { Component } from '@angular/core';
import { Observable, of } from 'rxjs';
import { delay } from 'rxjs/operators';
@Component({
selector: 'app-async-example',
template: `
<h2>AsyncPipe Example</h2>
<p>Data: {{ data$ | async }}</p>
`
})
export class AsyncExampleComponent {
data$: Observable<string> = of('Hello from Observable!').pipe(delay(2000));
}
Explanation:
of('Hello from Observable!')
creates an observable.delay(2000)
simulates an API delay.- The
async
pipe subscribes automatically and updates the template once data arrives. - No need to manually call
.subscribe()
in the component.
Example Using Promise
export class AsyncPromiseComponent {
promiseData = new Promise(resolve => {
setTimeout(() => resolve('Hello from Promise!'), 2000);
});
}
Template:
<p>{{ promiseData | async }}</p>
The AsyncPipe
unwraps the promise result automatically when it resolves.
9. Combining Multiple Pipes
You can combine multiple pipes in a single expression. Pipes are executed from left to right.
Example
export class CombinedPipeComponent {
today: Date = new Date();
}
Template:
<p>{{ today | date:'longDate' | uppercase }}</p>
Here, DatePipe
formats the date first, and then the UpperCasePipe
transforms the text to uppercase.
Output:
THURSDAY, OCTOBER 9, 2025
You can chain any number of pipes together to achieve complex transformations inline.
10. Handling Locales in Pipes
Pipes are locale-aware. Angular’s built-in pipes automatically adapt based on the app’s current locale setting.
To configure your app for a different locale:
Step 1: Import Locale Data
import { registerLocaleData } from '@angular/common';
import localeFr from '@angular/common/locales/fr';
registerLocaleData(localeFr);
Step 2: Provide the Locale in App Module
import { LOCALE_ID, NgModule } from '@angular/core';
@NgModule({
providers: [{ provide: LOCALE_ID, useValue: 'fr' }]
})
export class AppModule {}
Now all pipes (like DatePipe
, CurrencyPipe
, and DecimalPipe
) will automatically use the French locale.
11. Real-World Example: Displaying a Product List
Let’s combine several pipes in a practical example.
product-list.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-product-list',
templateUrl: './product-list.component.html'
})
export class ProductListComponent {
products = [
{ name: 'Laptop', price: 1200, added: new Date('2025-10-01'), discount: 0.15 },
{ name: 'Phone', price: 800, added: new Date('2025-09-20'), discount: 0.10 },
{ name: 'Tablet', price: 600, added: new Date('2025-09-25'), discount: 0.20 }
];
}
product-list.component.html
<h2>Product List</h2>
<table>
<tr>
<th>Name</th>
<th>Price</th>
<th>Added On</th>
<th>Discount</th>
</tr>
<tr *ngFor="let p of products">
<td>{{ p.name | uppercase }}</td>
<td>{{ p.price | currency:'USD':'symbol' }}</td>
<td>{{ p.added | date:'shortDate' }}</td>
<td>{{ p.discount | percent:'1.0-0' }}</td>
</tr>
</table>
Output Example
Name | Price | Added On | Discount |
---|---|---|---|
LAPTOP | $1,200.00 | 10/1/25 | 15% |
PHONE | $800.00 | 9/20/25 | 10% |
TABLET | $600.00 | 9/25/25 | 20% |
This demonstrates the real power of built-in pipes in day-to-day applications.
12. Performance Considerations
Pipes are pure by default, meaning they only recalculate when the input value changes. This makes them efficient because Angular doesn’t re-run them on every change detection cycle.
However, you can also create impure pipes (not recommended unless necessary) that run more frequently.
The AsyncPipe
is especially efficient because it handles subscriptions and unsubscriptions automatically.
13. Common Pitfalls
1. Using Pipes with Complex Objects
If you pass an object instead of a primitive to a pipe, Angular may not detect changes unless you create a new object reference.
2. Misusing AsyncPipe
The AsyncPipe
should only be used on Observables or Promises. Using it on static values will cause runtime errors.
3. Locale Configuration
If your app shows incorrect currency or date formats, ensure your locale data is registered and LOCALE_ID
is set properly.
14. Best Practices for Using Pipes
- Use pipes for view formatting, not complex logic.
- Keep templates readable by chaining only when necessary.
- Avoid performing expensive computations in custom pipes.
- Prefer built-in pipes over custom ones whenever possible.
- Use AsyncPipe instead of manual subscription for Observables in templates.
- Always specify locale if your app supports multiple languages.
- Reuse pipe logic consistently across your application.
15. Creating a Custom Pipe (for Comparison)
Although Angular provides many built-in pipes, you can create your own for specific needs.
Example: TitleCasePipe (built-in alternative exists, but we’ll reimplement it)
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({ name: 'titleCase' })
export class TitleCasePipe implements PipeTransform {
transform(value: string): string {
if (!value) return '';
return value
.split(' ')
.map(word => word[0].toUpperCase() + word.substr(1).toLowerCase())
.join(' ');
}
}
Template:
<p>{{ 'angular built in pipes' | titleCase }}</p>
Output:
Angular Built In Pipes
This shows how flexible the Angular pipe system really is.
Leave a Reply