Angular Pipes: Format Dates, Currency and Text

Angular Tutorial: Beginner to Advanced · 6. Reusable components · 4 min read · Updated

Data in your classes is usually in a raw form: a date as a timestamp, a price as a number, a name in any case. A pipe transforms a value for display, right in the template, with a vertical bar.

What you will learn

  • How to use the common built-in pipes
  • How to pass options to a pipe
  • How to write and use a custom pipe

Built-in pipes

Pipes live in @angular/common. Import the ones a component uses into its imports list:

// src/app/pipes-demo/pipes-demo.ts
import {
  CurrencyPipe,
  DatePipe,
  DecimalPipe,
  JsonPipe,
  PercentPipe,
  SlicePipe,
  TitleCasePipe,
  UpperCasePipe,
} from '@angular/common';
import { Component } from '@angular/core';
import { TruncatePipe } from '../truncate-pipe';

@Component({
  selector: 'app-pipes-demo',
  imports: [CurrencyPipe, DatePipe, DecimalPipe, JsonPipe, PercentPipe, SlicePipe, TitleCasePipe, UpperCasePipe, TruncatePipe],
  template: `
    <ul>
      <li>Date: {{ published | date: 'longDate' }}</li>
      <li>Short date: {{ published | date: 'dd/MM/yyyy' }}</li>
      <li>Price: {{ price | currency }}</li>
      <li>Price in euros: {{ price | currency: 'EUR' }}</li>
      <li>Number: {{ pi | number: '1.0-2' }}</li>
      <li>Percent: {{ ratio | percent }}</li>
      <li>Upper case: {{ name | uppercase }}</li>
      <li>Title case: {{ sentence | titlecase }}</li>
      <li>First three letters: {{ name | slice: 0 : 3 }}</li>
      <li>Object as JSON: <code>{{ user | json }}</code></li>
      <li>Custom pipe: {{ longText | truncate: 30 }}</li>
    </ul>
  `,
})
export class PipesDemo {
  protected readonly published = new Date(2026, 9, 10);
  protected readonly price = 1234.5;
  protected readonly pi = 3.14159;
  protected readonly ratio = 0.256;
  protected readonly name = 'angular';
  protected readonly sentence = 'learning angular is fun';
  protected readonly user = { name: 'Alex', roles: ['student'] };
  protected readonly longText = 'Angular pipes keep your templates clean and readable.';
}

A few things to notice:

  • A pipe follows the value with |, and options follow a colon: date: 'longDate'.
  • Several options are separated by colons, as in slice: 0 : 3.
  • The number pipe uses a format minInt.minFraction-maxFraction. '1.0-2' means at least one digit before the point, and up to two after.
  • The json pipe is handy while debugging because it prints any object as text.
  • Pipes can be chained: {{ name | slice: 0 : 3 | uppercase }}.

Pipes do not change the original value. They only change how it is displayed.

Locale

Dates, numbers and currencies follow a locale, which is en-US by default. Changing it takes a small setup with LOCALE_ID, which the official guide on internationalisation describes. For this course, the default is fine.

Write a custom pipe

When none of the built-in pipes does what you need, write your own. Generate one with ng generate pipe truncate, then edit it:

// src/app/truncate-pipe.ts
import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'truncate',
})
export class TruncatePipe implements PipeTransform {
  transform(value: string, limit = 40): string {
    if (value.length <= limit) {
      return value;
    }
    return value.slice(0, limit).trimEnd() + '…';
  }
}

The name is how you use it in a template. The transform method receives the value on the left of the bar, followed by any options. Using it is the same as a built-in pipe: add TruncatePipe to imports and write {{ longText | truncate: 30 }}, as the demo does.

Keep pipes pure: they should return the same output for the same input and avoid side effects, such as changing data or calling a server. Angular then only runs them when their inputs change, which keeps pages fast.

// src/app/app.ts
import { Component } from '@angular/core';
import { PipesDemo } from './pipes-demo/pipes-demo';

@Component({
  imports: [PipesDemo],
  selector: 'app-root',
  templateUrl: './app.html',
  styleUrl: './app.css',
})
export class App {}
<!-- src/app/app.html -->
<main>
  <h1>Pipes</h1>
  <app-pipes-demo />
</main>

Try it yourself

  1. Show today's date with new Date() and the format 'fullDate'.
  2. Write a pipe initials that turns "Ada Lovelace" into "AL".
  3. Chain uppercase and slice to show the first four letters of a name in capitals.

Quick check

  1. Which character applies a pipe to a value?
  2. What does a pipe change: the data or how it is displayed?
  3. Where do you list a pipe so that a template can use it?

Next, continue with Angular Built-in Pipes: Date, Async, KeyValue and Using Pipes in Code.

Frequently asked questions

Can a pipe call a server?

A pipe should stay simple and pure. Fetch data in a service and pass the result to the template. The async pipe is a special built-in that reads values from observables.

Is a pipe better than a method in a template?

For formatting, usually yes. A pure pipe only runs again when its input changes, while a method call in a template runs on every check.