Angular Tutorial 0/42 lessons ~6 min read Lesson 18

    Angular Pipes

    Learn Angular Pipes for presentation-layer data transformation, including built-in pipes, DatePipe, CurrencyPipe, DecimalPipe, PercentPipe, string pipes, JsonPipe, AsyncPipe, parameters, chaining, custom pipes, pure and impure pipes, performance, computed state, localization, and interview questions.

    Course progress0%
    Focus
    45 guided sections
    Practice signal
    Examples included
    Career prep
    Interview Q&A included

    Learning Objectives

    By the end of this lesson, you will understand:

    • What Pipes are in Angular and why they are useful for presentation-layer data transformation.
    • How pipe syntax, parameters, and chaining work.
    • How to use built-in Pipes such as DatePipe, CurrencyPipe, DecimalPipe, PercentPipe, string pipes, JsonPipe, and AsyncPipe.
    • How to create custom Pipes and how PipeTransform works.
    • How pure and impure Pipes interact with change detection and performance.
    • When to use Pipes, component methods, computed Signals, or Services.

    Introduction

    Imagine you're building an e-commerce application. Your backend returns product information like this:

    typescript
    {
    name: 'macbook pro',
    price: 129999.5,
    discount: 0.15,
    createdAt: '2026-07-18T10:30:00Z'
    }

    You do not want to display raw values like 129999.5 or 2026-07-18T10:30:00Z. You want user-friendly output such as Macbook Pro, ₹129,999.50, 15%, and 18 Jul 2026.

    text
    Raw Data
    Angular Pipe
    Formatted Data
    Template
    html
    {{ product.price | currency:'INR' }}

    The original data remains unchanged. Only its presentation is transformed.

    What Is an Angular Pipe?

    A Pipe transforms a value for display inside an Angular template.

    html
    {{ value | pipeName }}

    For example:

    html
    {{ username | uppercase }}

    If username is jagannath, the UI displays JAGANNATH. The original value remains unchanged.

    Why Do We Need Pipes?

    Without Pipes, components can become filled with formatting methods for prices, dates, percentages, and strings. Pipes keep templates expressive and components focused on state and behavior.

    html
    {{ product.price | currency:'INR' }}
    {{ product.createdAt | date:'mediumDate' }}
    {{ product.discount | percent }}
    {{ product.name | titlecase }}

    Pipe Architecture

    text
    Component Data
    Template
    Pipe
    Transformation
    Rendered Value

    Built-In Angular Pipes

    Angular provides useful built-in Pipes for common presentation transformations.

    • DatePipe
    • CurrencyPipe
    • DecimalPipe
    • PercentPipe
    • UpperCasePipe, LowerCasePipe, and TitleCasePipe
    • JsonPipe
    • AsyncPipe

    UpperCasePipe

    html
    {{ product.name | uppercase }}

    MacBook Pro becomes MACBOOK PRO.

    LowerCasePipe

    html
    {{ email | lowercase }}

    USER@EXAMPLE.COM becomes user@example.com.

    TitleCasePipe

    html
    {{ courseName | titlecase }}

    angular advanced development becomes Angular Advanced Development. Application-specific capitalization rules may still require custom logic.

    DatePipe

    Dates returned by APIs are often not formatted for users.

    html
    {{ createdAt | date }}
    {{ createdAt | date:'short' }}
    {{ createdAt | date:'mediumDate' }}
    {{ createdAt | date:'dd/MM/yyyy' }}

    Common Date Formats

    html
    {{ date | date:'short' }}
    {{ date | date:'medium' }}
    {{ date | date:'long' }}
    {{ date | date:'shortDate' }}
    {{ date | date:'mediumDate' }}
    {{ date | date:'fullDate' }}
    {{ date | date:'HH:mm' }}
    {{ date | date:'dd MMM yyyy' }}

    Actual formatting can depend on locale and timezone configuration.

    Date Formatting Architecture

    text
    Backend API
    ISO Date
    Angular Component
    DatePipe
    Localized Display

    DatePipe and Time Zones

    Date formatting can become complex in global applications. Define how the backend stores dates, whether timestamps are UTC, which timezone users expect, and whether a value represents an instant or a calendar-only date.

    A UTC timestamp such as 2026-07-18T23:30:00Z can appear as the next calendar day in some time zones.

    CurrencyPipe

    html
    {{ product.price | currency }}
    {{ product.price | currency:'INR' }}
    {{ product.price | currency:'USD' }}
    {{ product.price | currency:'EUR' }}

    CurrencyPipe formats values according to currency and locale configuration.

    Currency Formatting Architecture

    text
    129999.5
    CurrencyPipe
    ├── Currency Code
    └── Locale
    Formatted Currency

    This is better than manually writing a symbol because currency formatting includes symbols, grouping, decimal digits, and locale-specific conventions.

    DecimalPipe

    html
    {{ rating | number:'1.1-2' }}

    The format 1.1-2 means at least 1 integer digit, at least 1 fraction digit, and at most 2 fraction digits.

    Understanding Decimal Format

    text
    {minIntegerDigits}.{minFractionDigits}-{maxFractionDigits}

    Decimal formatting is useful for prices, measurements, ratings, financial displays, and statistical values.

    PercentPipe

    html
    {{ discount | percent }}

    If discount is 0.15, the output may be 15%. Remember that 1 represents 100%.

    JsonPipe

    html
    <pre>
    {{ user | json }}
    </pre>

    JsonPipe is useful for debugging and development. It generally should not be treated as polished production UI formatting.

    AsyncPipe

    AsyncPipe works with asynchronous values such as Observables and Promises.

    typescript
    products$ = this.productService.getProducts();
    html
    @if (products$ | async; as products) {
    @for (product of products; track product.id) {
    <p>{{ product.name }}</p>
    }
    }

    AsyncPipe Architecture

    text
    Observable
    AsyncPipe
    Subscribe
    Value Emitted
    Template Updated
    Component Destroyed
    Unsubscribe

    Why AsyncPipe Is Important

    Without AsyncPipe, components often manually subscribe, store emitted values, and manage lifecycle cleanup. With AsyncPipe, the template can consume asynchronous values directly.

    AsyncPipe and Multiple Subscriptions

    Using the same cold HTTP Observable through multiple AsyncPipe instances can create multiple subscriptions and duplicate API calls. Prefer unwrapping once and reusing the value inside the block.

    html
    @if (products$ | async; as products) {
    <p>Total: {{ products.length }}</p>
    @for (product of products; track product.id) {
    {{ product.name }}
    }
    }

    Passing Parameters to Pipes

    html
    {{ price | currency:'INR' }}
    {{ price | currency:'INR':'symbol':'1.2-2' }}

    Pipe parameters use colons. Each parameter configures the transformation.

    Chaining Pipes

    html
    {{ createdAt | date:'fullDate' | uppercase }}

    The output of one Pipe becomes the input of the next Pipe.

    Creating a Custom Pipe

    typescript
    import { Pipe, PipeTransform } from '@angular/core';
    @Pipe({
    name: 'truncate',
    standalone: true
    })
    export class TruncatePipe implements PipeTransform {
    transform(value: string, limit = 50): string {
    if (!value) {
    return '';
    }
    if (value.length <= limit) {
    return value;
    }
    return value.slice(0, limit) + '...';
    }
    }
    html
    {{ description | truncate:100 }}

    Custom Pipe Architecture

    text
    Input Value
    Custom Pipe
    transform()
    Transformation Logic
    Output Value

    Understanding PipeTransform

    Custom Pipes commonly implement PipeTransform, which requires a transform() method. Angular passes the input value and any Pipe parameters to this function.

    Real-World Custom Pipe Example: File Size

    If the backend returns 1048576 bytes, users may prefer 1 MB. A FileSizePipe can transform byte values into human-readable sizes for file upload, document management, and cloud storage features.

    Pure Pipes

    By default, Angular Pipes are pure. A pure Pipe executes when Angular detects a pure change to its input, such as primitive changes or object and array reference changes.

    text
    Input Reference
    Changed?
    / \
    No Yes
    │ │
    ▼ ▼
    Reuse Execute Pipe

    Pure Pipe Example

    If you mutate an array with push(), the array reference remains the same. A pure Pipe receiving that array may not execute solely because the internal contents changed.

    typescript
    this.products.push(product3); // same array reference
    this.products = [
    ...this.products,
    product3
    ]; // new array reference

    This is one reason immutable update patterns work well with Angular's reactive architecture.

    Impure Pipes

    typescript
    @Pipe({
    name: 'example',
    pure: false
    })

    Impure Pipes can execute very frequently during change detection. If the transformation is expensive, performance can suffer.

    Why Expensive Filtering Pipes Can Be Dangerous

    html
    @for (
    product of products | filter:searchTerm;
    track product.id
    ) {
    ...
    }

    If an impure filtering Pipe repeatedly filters thousands of records, every change detection cycle can become expensive.

    Better Filtering Architecture

    Instead of filtering large collections during template evaluation, derive filtered data when the relevant input changes.

    typescript
    searchTerm = signal('');
    products = signal<Product[]>([]);
    filteredProducts = computed(() => {
    const search = this.searchTerm().toLowerCase();
    return this.products().filter(product =>
    product.name.toLowerCase().includes(search)
    );
    });
    text
    Products + Search Term
    computed()
    Filtered Products
    Template

    Pipes vs Component Methods

    A method called from a template may be evaluated repeatedly during change detection. A pure Pipe can avoid recalculation when inputs have not changed. For complex derived state, a computed Signal may be more appropriate.

    Pipes vs Computed Signals

    Use a Pipe when the transformation is presentation-focused, reusable, stateless, and predictable. Use computed() when a value is derived from reactive application state or multiple Signals.

    Pipes vs Services

    Use a Pipe for presentation transformation. Use a Service for business logic, API communication, shared state, and domain operations. Critical discount or pricing rules should usually live in a domain/service layer, not a display Pipe.

    Enterprise Pipe Architecture

    text
    src/app/
    shared/
    └── pipes/
    ├── truncate.pipe.ts
    ├── file-size.pipe.ts
    └── highlight.pipe.ts
    features/
    └── orders/
    └── pipes/
    └── order-status-label.pipe.ts

    Reusable Pipes can live in shared areas. Feature-specific Pipes should remain close to their feature so the shared layer does not become a dumping ground.

    Real-World E-Commerce Example

    html
    <h2>{{ product.name | titlecase }}</h2>
    <p>{{ product.price | currency:'INR' }}</p>
    <p>Save {{ product.discount | percent }}</p>
    <p>Added: {{ product.createdAt | date:'mediumDate' }}</p>
    text
    Product DTO
    ├── Name -> TitleCasePipe
    ├── Price -> CurrencyPipe
    └── Date -> DatePipe
    Product UI

    Real-World Dashboard Example

    html
    <p>Revenue: {{ revenue | currency:'INR' }}</p>
    <p>Growth: {{ growth | percent:'1.1-2' }}</p>
    <p>Updated: {{ updatedAt | date:'short' }}</p>

    The component keeps original business values. Pipes handle presentation.

    Internationalization and Localization

    Currency, dates, numbers, and percentages are displayed differently depending on locale. Global applications should avoid assuming every user expects MM/DD/YYYY, USD, or English number formatting.

    text
    Raw Value
    Angular Pipe
    Configured Locale
    Localized Output

    Common Pitfalls

    Using Pipes for Business Logic

    Important domain rules should live in appropriate domain or service layers.

    Using Impure Pipes Without Understanding Performance

    Impure Pipes can run frequently, so avoid expensive operations inside them.

    Filtering Huge Collections in Templates

    For large datasets, prefer server-side filtering or efficiently derived reactive state.

    Using Multiple Async Pipes on the Same Cold HTTP Observable

    This can create multiple subscriptions and duplicate HTTP requests.

    Assuming Pipes Modify Original Data

    Pipes transform presentation output and normally do not mutate component properties.

    Using JsonPipe as Production UI

    JsonPipe is primarily useful for debugging.

    Ignoring Locale and Time Zones

    Date and currency formatting should consider global users and application requirements.

    Common Misconceptions

    Misconception

    Pipes permanently modify component data.

    Reality

    Pipes generally transform values for presentation without changing the original data.

    Misconception

    Every Pipe runs on every change detection cycle.

    Reality

    Pure and impure Pipes behave differently. Pure Pipes run based on pure input changes, while impure Pipes can execute much more frequently.

    Misconception

    AsyncPipe is only syntax sugar.

    Reality

    AsyncPipe also manages subscription lifecycle and integrates asynchronous values with Angular's template update mechanism.

    Misconception

    Pipes are the best solution for all transformations.

    Reality

    Pipes are best for presentation transformations. Business logic, complex state derivation, and data access belong elsewhere.

    Misconception

    An impure filtering Pipe is good for thousands of records.

    Reality

    Repeatedly filtering large collections during change detection can cause performance problems.

    Advanced interview questions

    Interview Prep

    Practice concise answers, then expand each card for the explanation.

    15 questions
    1BeginnerQuestionWhat is a Pipe in Angular?+

    Answer

    A Pipe transforms input data into a presentation-friendly output inside Angular templates without normally modifying the original value.
    2BeginnerQuestionName some built-in Angular Pipes.+

    Answer

    Common built-in Pipes include DatePipe, CurrencyPipe, DecimalPipe, PercentPipe, UpperCasePipe, LowerCasePipe, TitleCasePipe, JsonPipe, and AsyncPipe.
    3BeginnerQuestionWhat is AsyncPipe?+

    Answer

    AsyncPipe subscribes to an Observable or Promise, exposes the latest emitted value to the template, updates the view, and handles subscription cleanup when appropriate.
    4BeginnerQuestionWhat is the difference between pure and impure Pipes?+

    Answer

    A pure Pipe executes when Angular detects a pure input change. An impure Pipe can execute much more frequently during change detection.
    5BeginnerQuestionAre Pipes pure by default?+

    Answer

    Yes. Custom Angular Pipes are pure by default unless configured with pure: false.
    6IntermediateQuestionWhy might a pure Pipe not detect array.push()?+

    Answer

    push() mutates the same array reference. Pure Pipes primarily react to reference changes for objects and arrays.
    7IntermediateQuestionWhy should we avoid expensive impure Pipes?+

    Answer

    They may execute frequently during change detection, so filtering or sorting large collections can create significant performance problems.
    8IntermediateQuestionWhat is the difference between a Pipe and a component method?+

    Answer

    Template methods may be evaluated repeatedly during change detection. Pure Pipes can skip recalculation when inputs have not changed.
    9IntermediateQuestionWhat is the difference between a Pipe and a computed Signal?+

    Answer

    A Pipe is best for reusable presentation transformation. A computed Signal is better for derived state from reactive dependencies.
    10IntermediateQuestionHow do you pass arguments to a Pipe?+

    Answer

    Use colons, for example {{ price | currency:'INR' }}. Multiple arguments use additional colons.
    11AdvancedQuestionCan Pipes be chained?+

    Answer

    Yes. The output of one Pipe becomes the input to the next, such as {{ createdAt | date:'fullDate' | uppercase }}.
    12AdvancedQuestionHow do you create a custom Pipe?+

    Answer

    Create a class decorated with @Pipe() and usually implement PipeTransform. Put transformation logic in transform().
    13AdvancedQuestionShould filtering be implemented using a custom Pipe?+

    Answer

    Small pure transformations may be acceptable, but large or frequently changing filters should usually use server-side filtering or reactive derived state.
    14AdvancedQuestionCan multiple AsyncPipe usages cause multiple API calls?+

    Answer

    Potentially yes, if multiple AsyncPipe instances subscribe to the same cold HttpClient Observable.
    15AdvancedQuestionHow would you design Pipes in a large Angular application?+

    Answer

    Keep Pipes small, stateless, focused on presentation, and pure when possible. Place reusable Pipes in shared areas and feature-specific Pipes near their feature.

    Summary

    Angular Pipes provide a clean way to transform raw application data into user-friendly presentation values.

    text
    Raw Data
    Pipe
    Formatted Value
    User Interface

    Use Pipes to transform how data is displayed, not to hide complex application architecture inside the template. Used well, Pipes make templates cleaner, reusable, easier to localize, and easier to maintain. Misused with expensive impure transformations, they can create serious performance problems.

    Next Lesson: Angular Lifecycle Hooks - you'll learn component lifecycle hooks, execution order, cleanup strategies, DestroyRef, takeUntilDestroyed(), real-world use cases, performance mistakes, and enterprise best practices.

    Ready to mark this lesson complete?Track your journey across the entire course.