Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Chapter 13: Pipes and Defer in Angular

Pipes are one of Angular’s most powerful template features. They let you transform values for display without changing the underlying data. Meanwhile, Angular v17 introduced @defer blocks, which delay rendering until certain conditions are met. Together, these features improve readability, performance, and user experience.


13.1 What Are Pipes?

A pipe is a function that transforms data in templates.

Example:

<p>{{ today | date }}</p>

Here, the date pipe formats a Date object into a human-readable string.


13.2 Built-in Pipes

Angular ships with many useful pipes:

  • DatePipe: {{ today | date:'short' }}
  • CurrencyPipe: {{ price | currency:'USD' }}
  • DecimalPipe: {{ num | number:'1.2-2' }}
  • PercentPipe: {{ ratio | percent }}
  • AsyncPipe: {{ data$ | async }}
  • SlicePipe: {{ items | slice:0:3 }}

✅ Pipes are pure by default — they only re-run when input values change.


13.3 Custom Pipes

You can create your own pipes for specific transformations.

Example: CapitalizePipe

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

@Pipe({
  name: 'capitalize',
  standalone: true
})
export class CapitalizePipe implements PipeTransform {
  transform(value: string): string {
    return value.charAt(0).toUpperCase() + value.slice(1);
  }
}

Usage:

<p>{{ 'angular' | capitalize }}</p>
<!-- Output: Angular -->

13.4 Pure vs Impure Pipes

  • Pure pipes (default): Only re-run when input changes (efficient).
  • Impure pipes (pure: false): Re-run on every change detection cycle.

Use impure pipes sparingly (e.g., for filtering arrays in real time).


13.5 The Async Pipe

The async pipe is special: it subscribes to Observables or Promises automatically and unsubscribes when the component is destroyed.

Example:

<p *ngIf="user$ | async as user">Hello {{ user.name }}</p>

✅ Avoids manual .subscribe() and memory leaks.


13.6 Pipes vs Signals

With Angular signals, some transformations can move into computed signals.

Example with signals:

name = signal('angular');
capitalized = computed(() => this.name().toUpperCase());

Template:

<p>{{ capitalized() }}</p>

✅ Use pipes for template-level formatting.
✅ Use signals for state transformations in TypeScript.


13.7 The New @defer Block

Angular v17 introduced @defer, a structural block directive that delays rendering of parts of the template until:

  • The component is idle.
  • A specific trigger happens.
  • Or manually specified conditions are met.

This improves performance by not rendering heavy components immediately.

Example: Lazy Component Rendering

@defer {
  <expensive-chart></expensive-chart>
} @placeholder {
  <p>Loading chart...</p>
}

✅ The <expensive-chart> component is only rendered when the app is idle.
✅ @placeholder shows interim UI.


Example: Conditional Defer with Triggers

@defer (on viewport) {
  <app-ads-banner></app-ads-banner>
}

Here, the banner loads only when it enters the viewport (like lazy-loading images).


Example: Defer with Timer

@defer (on timer(5s)) {
  <app-hint-message></app-hint-message>
}

This shows a hint only after 5 seconds.


13.8 Pipes vs @defer

FeaturePipes@defer
PurposeTransform values for displayControl when to render content
ScopeData formatting in templatesUI performance optimization
Example`{{ pricecurrency }}`
ComplementWorks with @defer to format valuesWorks with pipes for final output

13.9 Summary

  • Pipes transform data directly in templates.
  • Angular ships with powerful built-in pipes (date, async, currency, etc.).
  • You can create custom pipes for reusable formatting.
  • Pipes are pure by default but can be impure.
  • Signals can handle some transformations outside templates.
  • The new @defer block delays rendering for better performance.
  • Together, pipes and @defer improve both data presentation and app responsiveness.