🅰️ Angular Q60 / 125

Explain Angular pipes lifecycle.

AI-Powered Answer ✓ Answered

Angular pipes are powerful tools used to transform data within templates, allowing for display-specific formatting, filtering, and sorting without altering the underlying data. Understanding their lifecycle primarily revolves around how and when they are executed by Angular's change detection mechanism, distinguishing between pure and impure pipes.

What are Angular Pipes?

Pipes are functions that accept an input value and return a transformed value. They are used in Angular templates to enhance data presentation, similar to filters in other frameworks. Angular provides several built-in pipes (e.g., DatePipe, CurrencyPipe, SlicePipe) and also allows for custom pipe creation.

html
<p>Today's date: {{ currentDate | date:'fullDate' }}</p>
<p>Price: {{ productPrice | currency:'USD':'symbol':'1.2-2' }}</p>
<p>Uppercase: {{ 'hello angular' | uppercase }}</p>

Pure vs. Impure Pipes

The core of understanding Angular pipe lifecycle is the distinction between pure and impure pipes. This distinction dictates when a pipe's transform method is executed and is crucial for performance optimization.

Pure Pipes

By default, all custom pipes are pure. A pure pipe is executed only when its input value is detected to have changed. Angular performs a fast check by comparing primitive input values (string, number, boolean, symbol) by reference and object references (Date, Array, Function, Object) by reference. If the reference has not changed, the pipe is not re-executed, and the previously computed result is returned. This behavior is called memoization.

  • Executed only if its input primitive value changes.
  • Executed only if its input object reference changes (not if properties of the object change).
  • Highly performant due to memoization; results are cached.
typescript
import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'myPurePipe',
  pure: true // This is the default and can be omitted
})
export class MyPurePipe implements PipeTransform {
  transform(value: number): number {
    console.log('Pure pipe transform executed');
    return value * 2;
  }
}

Impure Pipes

An impure pipe is executed during every change detection cycle, regardless of whether its input values have changed. This means it will re-run even if only a property within an input object (whose reference remains the same) is modified. While necessary for certain scenarios (like filtering an array when its contents change but its reference doesn't), impure pipes can have a significant performance impact if not used carefully due to frequent re-execution.

  • Executed during every change detection cycle (e.g., component event, HTTP response, route change).
  • Used when transformations depend on mutable state or asynchronous operations.
  • Can impact performance if transformations are complex or frequent.
typescript
import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'myImpurePipe',
  pure: false // Explicitly declared as impure
})
export class MyImpurePipe implements PipeTransform {
  transform(items: string[]): string[] {
    console.log('Impure pipe transform executed');
    // Example: filtering an array when its content changes
    return items.filter(item => item.startsWith('A'));
  }
}

Lifecycle and Change Detection

The lifecycle of an Angular pipe is inherently tied to Angular's change detection mechanism. When Angular runs change detection, it checks for changes in component properties that are bound in the template. If a bound property is an input to a pipe, Angular determines whether the pipe needs to be re-executed based on its purity.

Pipe TypeExecution Trigger
Pure PipeInput primitive value changes OR input object/array reference changes.
Impure PipeEvery change detection cycle (e.g., user events, timer events, XHR calls, Promise resolutions).

Performance Considerations

Understanding the pipe lifecycle is crucial for writing performant Angular applications. Overuse of impure pipes or inefficient logic within them can lead to significant performance bottlenecks, as they can trigger costly re-computations on every change detection cycle.

  • Always prefer pure pipes over impure pipes when possible.
  • If an impure pipe is necessary (e.g., for filtering an array whose items change), ensure the transformation logic is as lightweight and efficient as possible.
  • Consider making your data immutable; by creating new object/array references when data changes, you can leverage pure pipes more effectively.
  • For complex filtering/sorting of large datasets, consider performing the transformation within the component logic rather than repeatedly in an impure pipe.