Pipes
Pipes are data transformation functions usable directly from the template in order to transform the data to be displayed at binding time. They are interesting in two main ways:
- they don't require to change the data in the component so that it is displayed in a user-friendly way
- they are declared once and can be reused in as many components as needed as they are independent from them
Syntax
Angular pipe syntax is inspired by the unix shell pipes:
<div>{{ user().lastName | uppercase }}</div>
Parameters can be passed to pipes. They are placed after the pipe's name and separated by colons:
<div>{{ user().registrationDate | date:'dd/MM/yyyy' }}</div>
<div>{{ user().registrationDate | date:'dd/MM/yyyy hh:mm':'UTC' }}</div>
<div>{{ user().registrationDate | date:'dd/MM/yyyy hh:mm':'+0200':'fr' }}</div>
Pipes can be chained:
<div>{{ user().birthDate | date | uppercase }}</div>
Built-in pipes
Angular provides over a dozen built-in pipes to cover common use cases. Here is a complete list of them:
AsyncPipeunwraps a value from an asynchronous primitiveCurrencyPipetransforms a number to a currency string according to locale rulesDatePipeformats a date value according to locale rulesDecimalPipeformats a value according to digit options and locale rulesI18nPluralPipemaps a value to a string that pluralizes the value according to locale rulesI18nSelectPipegeneric selector that displays the string that matches the current valueJsonPipeconverts a value into its JSON-format representation, useful for debuggingKeyValuePipetransforms Object or Map into an array of key value pairsLowerCasePipetransforms text to all lower casePercentPipetransforms a number to a percentage string, formatted according to locale rulesSlicePipecreates a new Array or String containing a subset (slice) of the elementsTitleCasePipetransforms text to title caseUpperCasePipetransforms text to all upper case
Import
Pipes are not part of the default imports of a standalone component. You have to make the import yourself: add the class of the pipe to the imports array of your component's @Component decorator to make it available in the template.
Exercise: Format the price (in EUR) and the date ('EEEE dd MMMM y'), both in French
Custom pipe
If built-in pipes do not cover a use case you encounter, Angular gives you the opportunity to create a custom one.
Creating a custom Pipe requires you to:
- create a class that implements the
PipeTransforminterface - decorate it with the
@Pipe()decorator
The CLI will take care of these points for us via the following command:
ng generate pipe <name>
It generates the following file:
import { Pipe, PipeTransform } from '@angular/core'
@Pipe({
name: 'demo'
})
export class DemoPipe implements PipeTransform {
transform(value: unknown, ...args: unknown[]): unknown {
return null
}
}
The transform method's first argument is the value on which the pipe is applied, the method then takes any number of arguments. It is recommended to type all the arguments as well as the return type.
The pipe's name should be in lowerCamelCase. It is a good practice to make it start with your app's initials, just like for the selector of your components.
Just like any other class, pipes can make use of their constructor to benefit from dependency injection. It is possible to inject another pipe for instance. This is particularly useful when a built-in pipe is going to be used throughout the application with the same parameters. A custom pipe can serve as a wrapper so as to simplify the use of a built-in pipe.
In the following example, the discounted price is calculated given a discount rate. No catalogue data in the component is mutated to display the new price.
Using a pipe outside the template
It is also possible to use pipes in a component class by injecting via the inject method and calling its transform method. The pipe needs to be added to the providers array of the component decorator or ApplicationConfig. When not used in the template, the pipe doesn't need to be present in the imports array of the component decorator.
import { Component, inject, signal } from '@angular/core'
import { UpperCasePipe } from '@angular/common'
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
providers: [ UpperCasePipe ]
})
export class AppComponent {
private readonly upperCasePipe = inject(UpperCasePipe)
protected readonly title = signal(this.upperCasePipe.transform('title'))
}
Practical work: format rating
- Create a
starRatingpipe using the CLI in the folderapp/pipes. - Implement the inside of the transform method so that a film's metascore is displayed with ★ to five ★★★★★ rating. Change the transform signature to make it more specific to your case.
- Use this pipe in the template of the
LoginFormComponent. - Commit
Expected result


To go further
The difference between pure and impure pipes