- Use
pipes
to transform strings, currency amounts, dates, and other data for display.
- Pipes are simple functions to use in template expressions to accept an input value and return a transformed value. Pipes are useful because you can use them throughout your application, while only declaring each pipe once. For example, you would use a pipe to show a date as April 15, 1988 rather than the raw string format.
-
Angular provides built-in pipes for typical data transformations, including transformations for internationalization (i18n), which use locale information to format data. The following are commonly used built-in pipes for data formatting:
- DatePipe: Formats a date value according to locale rules.
- UpperCasePipe: Transforms text to all upper case.
- LowerCasePipe: Transforms text to all lower case.
- CurrencyPipe: Transforms a number to a currency string, formatted according to locale rules.
- DecimalPipe: Transforms a number into a string with a decimal point, formatted according to locale rules.
- PercentPipe: Transforms a number to a percentage string, formatted according to locale rules.
-
The pipe operator has a higher precedence than the ternary operator (?:), which means a ? b : c | x is parsed as a ? b : (c | x). The pipe operator cannot be used without parentheses in the first and second operands of ?:.
-
Due to precedence, if you want a pipe to apply to the result of a ternary, wrap the entire expression in parentheses; for example, (a ? b : c) | x.
- src/app/precedence.component.html
<!-- use parentheses in the third operand so the pipe applies to the whole expression --> {{ (true ? 'true' : 'false') | uppercase }}
- src/app/precedence.component.html
-
To apply a pipe, use the pipe operator (|) within a template expression as shown in the following code example, along with the name of the pipe, which is
date
for the built-inDatePipe
. -
app.component.html uses
date
in a separate template to display a birthday.<p>The hero's birthday is {{ birthday | date }}</p>
-
hero-birthday1.component.ts uses the same pipe as part of an in-line template in a component that also sets the birthday value.
import { Component } from '@angular/core'; @Component({ selector: 'app-hero-birthday', template: "<p>The hero's birthday is {{ birthday | date }}</p>" }) export class HeroBirthdayComponent { birthday = new Date(1988, 3, 15); // April 15, 1988 -- since month parameter is zero-based }
-
Use optional parameters to fine-tune a pipe's output. For example, use the
CurrencyPipe
with a country code such as EUR as a parameter. The template expression {{ amount | currency:'EUR' }} transforms the amount to currency in euros. Follow the pipe name (currency) with a colon (:) and the parameter value ('EUR'). -
If the pipe accepts multiple parameters, separate the values with colons. For example, {{ amount | currency:'EUR':'Euros '}} adds the second parameter, the string literal 'Euros ', to the output string. Use any valid template expression as a parameter, such as a string literal or a component property.
-
Some pipes require at least one parameter and allow more optional parameters, such as
SlicePipe
. For example, {{ slice:1:5 }} creates a new array or string containing a subset of the elements starting with element 1 and ending with element 5.
-
The
app.component.html
template uses a format parameter for the DatePipe (named date) to show the date as 04/15/88.<p>The hero's birthday is {{ birthday | date:"MM/dd/yy" }} </p>
-
The
hero-birthday2.component.ts
component binds the pipe's format parameter to the component'sformat
property in the template section, and adds a button for a click event bound to the component'stoggleFormat()
method.template: ` <p>The hero's birthday is {{ birthday | date:format }}</p> <button type="button" (click)="toggleFormat()">Toggle Format</button> `
-
The
hero-birthday2.component.ts
component'stoggleFormat()
method toggles the component's format property between a short form ('shortDate') and a longer form ('fullDate').export class HeroBirthday2Component { birthday = new Date(1988, 3, 15); // April 15, 1988 -- since month parameter is zero-based toggle = true; // start with true == shortDate get format() { return this.toggle ? 'shortDate' : 'fullDate'; } toggleFormat() { this.toggle = !this.toggle; } }
-
Clicking the Toggle Format button alternates the date format between 04/15/1988 and Friday, April 15, 1988.
-
Chain pipes so that the output of one pipe becomes the input to the next.
The chained hero's birthday is {{ birthday | date | uppercase}}
The chained hero's birthday is {{ birthday | date:'fullDate' | uppercase}}
- Create custom pipes to encapsulate transformations that are not provided with the built-in pipes.
- To mark a class as a pipe and supply configuration metadata, apply the
@Pipe decorator
to the class.
- Implement the
PipeTransform
interface in your custom pipe class to perform the transformation. - Angular invokes the
transform
method with the value of a binding as the first argument, and any parameters as the second argument in list form, and returns the transformed value.
-
In a game, you might want to implement a transformation that raises a value exponentially to increase a hero's power. For example, if the hero's score is 2, boosting the hero's power exponentially by 10 produces a score of 1024. Use a custom pipe for this transformation.
-
The
exponential-strength.pipe.ts
component defines a custom pipe namedexponentialStrength
with thetransform
method that performs the transformation. It defines an argument to thetransform
method (exponent
) for a parameter passed to the pipe. -
The
power-booster.component.ts
component demonstrates how to use the pipe, specifying a value (2) and the exponent parameter (10). -
src/app/exponential-strenth.pipe.ts
import { Pipe, PipeTransform } from '@angular/core'; /* * Raise the value exponentially * Takes an exponent argument that defaults to 1. * Usage: * value | exponentialStrength:exponent * Example: * {{ 2 | exponentialStrength:10 }} * formats to: 1024 */ @Pipe({name: 'exponentialStrength'}) export class ExponentialStrengthPipe implements PipeTransform { transform(value: number, exponent = 1): number { return Math.pow(value, exponent); } }
-
src/app/power-booster.component.ts
import { Component } from '@angular/core'; @Component({ selector: 'app-power-booster', template: ` <h2>Power Booster</h2> <p>Super power boost: {{2 | exponentialStrength: 10}}</p> ` }) export class PowerBoosterComponent { }
- Decorator that marks a class as pipe and supplies configuration metadata.
- Options
Option Description name The pipe name to use in template bindings. Typically uses lowerCamelCase because the name cannot contain hyphens. pure? When true, the pipe is pure, meaning that the transform() method is invoked only when its input arguments change. Pipes are pure by default. standalone? Angular pipes marked as standalone do not need to be declared in an NgModule. Such pipes don't depend on any "intermediate context" of an NgModule (ex. configured providers).
-
Unwraps a value from an asynchronous primitive.
{{ obj_expression | async }}
-
Input value
- obj: Observable | Subscribable | Promise
-
Description
- The async pipe subscribes to an Observable or Promise and returns the latest value it has emitted. When a new value is emitted, the async pipe marks the component to be checked for changes. When the component gets destroyed, the async pipe unsubscribes automatically to avoid potential memory leaks. When the reference of the expression changes, the async pipe automatically unsubscribes from the old Observable or Promise and subscribes to the new one.
-
Usage notes
-
Examples
-
This example binds a Promise to the view. Clicking the Resolve button resolves the promise.
@Component({ selector: 'async-promise-pipe', template: `<div> <code>promise|async</code>: <button (click)="clicked()">{{ arrived ? 'Reset' : 'Resolve' }}</button> <span>Wait for it... {{ greeting | async }}</span> </div>` }) export class AsyncPromisePipeComponent { greeting: Promise<string>|null = null; arrived: boolean = false; private resolve: Function|null = null; constructor() { this.reset(); } reset() { this.arrived = false; this.greeting = new Promise<string>((resolve, reject) => { this.resolve = resolve; }); } clicked() { if (this.arrived) { this.reset(); } else { this.resolve!('hi there!'); this.arrived = true; } } }
-
It's also possible to use
async
with Observables. The example below binds the time Observable to the view. The Observable continuously updates the view with the current time.@Component({ selector: 'async-observable-pipe', template: '<div><code>observable|async</code>: Time: {{ time | async }}</div>' }) export class AsyncObservablePipeComponent { time = new Observable<string>((observer: Observer<string>) => { setInterval(() => observer.next(new Date().toString()), 1000); }); }
-
-
-
Task 1
- Build a reverse pipe that basically reverses a string. (There is a reverse method in JavaScript that you can use but it only works on “real arrays”, not on string which technically is array of characters) (Hint: You would have to split the string by empty character first, then apply reverse and then join it together with empty character to get a string again)
-
Task 2
- Build a sort pipe, which sorts this list by name of the instance, production user database and so on.
-
Q&A 01:
-
what would be an example template syntax usage of this custom pipe?
@Pipe({ name: 'truncate' }) export class TruncatePipe implements PipeTransform { transform(value: string, maxLength: number, showEllipsis: boolean) { const newValue = maxLength ? value.substr(0, maxLength) : value; return showEllipsis ? `${newValue}...` : newValue; } }
============================
- A): TRUE
{{ 'some long text' | truncate: 10: true }}
B):
{{ 'some long text' | truncate: 10 }}
C):
{{ 'some long text' | truncate }}
D):
all of these answers
- A): TRUE
-