Built-in Pipes in Angular

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:

  1. What pipes are and why they’re useful
  2. How to use built-in pipes
  3. Detailed explanation of common built-in pipes
  4. Syntax, parameters, and examples for each pipe
  5. Best practices when using pipes
  6. Performance and async data handling with AsyncPipe
  7. Combining multiple pipes in templates
  8. Common pitfalls and troubleshooting
  9. 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:

  1. DatePipe – formats date values.
  2. CurrencyPipe – formats numbers as currency.
  3. DecimalPipe – formats decimal numbers.
  4. PercentPipe – formats numbers as percentages.
  5. 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

FormatExample 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 digits
    • 2 → minimum fraction digits
    • 2 → 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: `
&lt;h2&gt;AsyncPipe Example&lt;/h2&gt;
&lt;p&gt;Data: {{ data$ | async }}&lt;/p&gt;
` }) 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(() =&gt; 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>
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Price&lt;/th&gt;
&lt;th&gt;Added On&lt;/th&gt;
&lt;th&gt;Discount&lt;/th&gt;
</tr> <tr *ngFor="let p of products">
&lt;td&gt;{{ p.name | uppercase }}&lt;/td&gt;
&lt;td&gt;{{ p.price | currency:'USD':'symbol' }}&lt;/td&gt;
&lt;td&gt;{{ p.added | date:'shortDate' }}&lt;/td&gt;
&lt;td&gt;{{ p.discount | percent:'1.0-0' }}&lt;/td&gt;
</tr> </table>

Output Example

NamePriceAdded OnDiscount
LAPTOP$1,200.0010/1/2515%
PHONE$800.009/20/2510%
TABLET$600.009/25/2520%

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

  1. Use pipes for view formatting, not complex logic.
  2. Keep templates readable by chaining only when necessary.
  3. Avoid performing expensive computations in custom pipes.
  4. Prefer built-in pipes over custom ones whenever possible.
  5. Use AsyncPipe instead of manual subscription for Observables in templates.
  6. Always specify locale if your app supports multiple languages.
  7. 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 =&gt; word&#91;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.


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *