Pipes

By Syncfusion®, Inc. · Last updated

What pipes are and why to use them, the built-in date, currency, number, percent, case and json pipes, chaining pipes, pipe parameters, and writing a custom pipe.

What Are Pipes?

A pipe is a function that formats a value inside a template, without changing the value stored in the class. You apply a pipe with the | character: {{ value | pipeName }}.

The value on the left goes into the pipe. The pipe returns the formatted text, and Angular displays that text.

Real-World Example

An orders API returns createdAt: "2026-03-15T09:30:00Z" and total: 54999. The orders table must show 15 Mar 2026 and ₹54,999.00.

Pipes do this formatting in the template, so the component keeps the raw API values for sorting, filtering and calculations.

54999value in the class| currency: 'INR'the pipe₹54,999.00text on screenThe class still stores 54999, so calculations stay correct.

A pipe formats the value on its way to the screen.

Why Pipes?

Without pipes, every component would need its own formatting methods, such as formatDate() and formatPrice(). That code is repeated across the app and easy to get wrong.

Pipes solve this:

  • Reusable. One pipe formats values in every template of the app.
  • Raw data stays raw. The class keeps numbers and dates, so calculations stay correct.
  • Locale-aware. Built-in pipes follow the app's locale for dates, currencies and number separators.
  • Fast. By default, Angular runs a pipe again only when its input value changes.
  • Readable. {{ total | currency:'INR' }} states its purpose clearly in the template.

Built-in Pipes

Angular ships common pipes in @angular/common. Import each pipe you use into the component's imports list.

PipeTemplate nameExample inputExample output
DatePipedate'2026-03-15'Mar 15, 2026
CurrencyPipecurrency54999$54,999.00
DecimalPipenumber1234.51,234.5
PercentPipepercent0.25626%
UpperCasePipeuppercase'angular'ANGULAR
LowerCasePipelowercase'ANGULAR'angular
TitleCasePipetitlecase'order shipped'Order Shipped
JsonPipejson{ id: 7 }{ "id": 7 }

The examples on this page use the default en-US locale, so numbers use western grouping: 1,284,503. To use Indian grouping (12,84,503) and Indian date formats, register the en-IN locale data with registerLocaleData and provide LOCALE_ID in app.config.ts.

DatePipe

DatePipe formats a date, a timestamp or an ISO date string. Pass a format name or a pattern as a parameter.

DatePipe formats one date in several ways

import { Component } from '@angular/core';
import { DatePipe } from '@angular/common';

@Component({
  selector: 'app-root',
  imports: [DatePipe],
  template: `
    <p>Default: {{ orderDate | date }}</p>
    <p>Short: {{ orderDate | date: 'shortDate' }}</p>
    <p>Custom: {{ orderDate | date: 'dd MMM yyyy' }}</p>
    <p>Full: {{ orderDate | date: 'fullDate' }}</p>
  `,
})
export class App {
  orderDate = new Date(2026, 2, 15);
}

Common pattern letters are dd (day), MMM (short month name), MM (month number), yyyy (year), HH:mm (24-hour time) and h:mm a (12-hour time).

CurrencyPipe

CurrencyPipe formats a number as money. The first parameter is the ISO currency code, such as 'INR', 'USD' or 'EUR'.

CurrencyPipe formats prices in different currencies

import { Component } from '@angular/core';
import { CurrencyPipe } from '@angular/common';

@Component({
  selector: 'app-root',
  imports: [CurrencyPipe],
  template: `
    <p>Default: {{ price | currency }}</p>
    <p>Rupees: {{ price | currency: 'INR' }}</p>
    <p>Euros: {{ price | currency: 'EUR' }}</p>
    <p>No decimals: {{ price | currency: 'INR' : 'symbol' : '1.0-0' }}</p>
  `,
})
export class App {
  price = 54999;
}

DecimalPipe

DecimalPipe, used as number, adds thousands separators and controls decimal places. Its parameter has the form 'minInteger.minFraction-maxFraction'.

DecimalPipe controls separators and decimal places

import { Component } from '@angular/core';
import { DecimalPipe } from '@angular/common';

@Component({
  selector: 'app-root',
  imports: [DecimalPipe],
  template: `
    <p>Page views: {{ views | number }}</p>
    <p>Rating: {{ rating | number: '1.1-1' }}</p>
    <p>Distance: {{ distance | number: '1.2-2' }} km</p>
  `,
})
export class App {
  views = 1284503;
  rating = 4.4666;
  distance = 7.5;
}

'1.2-2' means: at least 1 digit before the decimal point, and exactly 2 digits after it.

PercentPipe

PercentPipe multiplies a number by 100 and adds a percent sign. It accepts the same digit format as DecimalPipe.

PercentPipe turns ratios into percentages

import { Component } from '@angular/core';
import { PercentPipe } from '@angular/common';

@Component({
  selector: 'app-root',
  imports: [PercentPipe],
  template: `
    <p>Conversion rate: {{ conversion | percent }}</p>
    <p>Test coverage: {{ coverage | percent: '1.1-1' }}</p>
  `,
})
export class App {
  conversion = 0.256;
  coverage = 0.8734;
}

UpperCasePipe, LowerCasePipe and TitleCasePipe

These three pipes change the letter case of text.

  • uppercase changes every letter to a capital letter.
  • lowercase changes every letter to a small letter.
  • titlecase capitalises the first letter of each word.

Case pipes normalise text from an API

import { Component } from '@angular/core';
import { LowerCasePipe, TitleCasePipe, UpperCasePipe } from '@angular/common';

@Component({
  selector: 'app-root',
  imports: [UpperCasePipe, LowerCasePipe, TitleCasePipe],
  template: `
    <p>Coupon code: {{ coupon | uppercase }}</p>
    <p>Email: {{ email | lowercase }}</p>
    <p>Status: {{ status | titlecase }}</p>
  `,
})
export class App {
  coupon = 'save20now';
  email = 'Asha.Kumar@Example.COM';
  status = 'out for delivery';
}

JsonPipe

JsonPipe converts an object to formatted JSON text. Developers use it to inspect data while debugging a template.

JsonPipe prints an object for debugging

import { Component } from '@angular/core';
import { JsonPipe } from '@angular/common';

@Component({
  selector: 'app-root',
  imports: [JsonPipe],
  template: `<pre>{{ user | json }}</pre>`,
})
export class App {
  user = { id: 42, name: 'Ravi', roles: ['editor', 'reviewer'] };
}

Wrap json output in a <pre> element. <pre> keeps the line breaks and indentation, so nested objects stay readable.

Chaining Pipes

You can apply several pipes to one value by writing them one after another. This is called chaining. Angular runs the pipes from left to right, and each pipe receives the output of the previous one.

Chained pipes run from left to right

import { Component } from '@angular/core';
import { DatePipe, UpperCasePipe } from '@angular/common';

@Component({
  selector: 'app-root',
  imports: [DatePipe, UpperCasePipe],
  template: `
    <p>Delivery: {{ deliveryDate | date: 'EEEE, d MMMM' | uppercase }}</p>
  `,
})
export class App {
  deliveryDate = new Date(2026, 2, 18);
}

First date produces Wednesday, 18 March. Then uppercase produces WEDNESDAY, 18 MARCH.

The order matters. {{ name | uppercase | slice: 0 : 3 }} is valid, but putting a date pipe after uppercase fails, because uppercase returns text that is no longer a date.

Pipe Parameters

A pipe parameter changes how a pipe formats its value. You write a colon after the pipe name, then the parameter value. Separate several parameters with more colons.

{{ value | pipeName : parameter1 : parameter2 }}
ExamplePipeParameters
{{ d | date: 'shortTime' }}dateformat
{{ p | currency: 'INR' : 'code' }}currencycurrency code, display style
{{ n | number: '1.0-2' }}numberdigit format
{{ text | slice: 0 : 20 }}slicestart index, end index

Parameters can also be expressions from the class, such as {{ price | currency: selectedCurrency }}. When selectedCurrency changes, the pipe runs again.

Custom Pipes

A custom pipe is your own formatting function, packaged so every template can use it.

You create one with the @Pipe decorator and a class that has a transform method. Angular calls transform with the value from the left side of |, followed by any parameters. In a project, the CLI creates the file for you:

ng generate pipe file-size

A custom pipe formats file sizes

import { Component, Pipe, PipeTransform } from '@angular/core';

@Pipe({ name: 'fileSize' })
export class FileSizePipe implements PipeTransform {
  transform(bytes: number, decimals: number = 1): string {
    if (bytes < 1024) return bytes + ' B';
    const units = ['KB', 'MB', 'GB'];
    let size = bytes / 1024;
    let unit = 0;
    while (size >= 1024 && unit < units.length - 1) {
      size = size / 1024;
      unit++;
    }
    return size.toFixed(decimals) + ' ' + units[unit];
  }
}

@Component({
  selector: 'app-root',
  imports: [FileSizePipe],
  template: `
    @for (file of files; track file.name) {
      <p>{{ file.name }}: {{ file.bytes | fileSize }}</p>
    }
    <p>Precise: {{ 5368709120 | fileSize: 2 }}</p>
  `,
})
export class App {
  files = [
    { name: 'notes.txt', bytes: 820 },
    { name: 'photo.jpg', bytes: 2457600 },
    { name: 'backup.zip', bytes: 1610612736 },
  ];
}

A custom pipe has three parts:

  1. @Pipe({ name: 'fileSize' }) sets the name used in templates.
  2. implements PipeTransform declares that the class has a transform method.
  3. transform(value, ...params) returns the formatted result.

Custom pipes are pure by default. Angular runs a pure pipe again only when its input value or a parameter changes. This keeps templates fast. Keep transform free of side effects, so the same input always gives the same output.

Common Mistakes

MistakeWhat you seeFix
Pipe not importedNG0302: The pipe 'date' could not be foundAdd DatePipe (or the pipe you use) to imports
Using the class name in the template{{ d | DatePipe }} is not foundUse the template name: {{ d | date }}
Spaces in the digit format'1.2 - 2' causes a format errorWrite it without spaces: '1.2-2'
percent on a whole number25 shows as 2,500%Pass a ratio: 0.25
Chaining in the wrong orderA pipe receives text it cannot readPut pipes that need raw values first
Formatting in the class insteadDuplicated formatting code in many componentsMove the formatting into a pipe

Check Yourself

Exercises

What to Remember

  • A pipe formats a value for display with {{ value | pipe }} and leaves the class data unchanged.
  • Built-in pipes cover dates, currency, numbers, percentages, letter case and JSON. Pass settings with : and chain pipes from left to right.
  • A custom pipe is a class with @Pipe and a transform method.

Next: Event Handling, how to respond to clicks, key presses and form changes.