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.
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, andAsyncPipe. - How to create custom Pipes and how
PipeTransformworks. - 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:
{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.
Raw Data│▼Angular Pipe│▼Formatted Data│▼Template
{{ 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.
{{ value | pipeName }}
For example:
{{ 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.
{{ product.price | currency:'INR' }}{{ product.createdAt | date:'mediumDate' }}{{ product.discount | percent }}{{ product.name | titlecase }}
Pipe Architecture
Component Data│▼Template│▼Pipe│▼Transformation│▼Rendered Value
Built-In Angular Pipes
Angular provides useful built-in Pipes for common presentation transformations.
DatePipeCurrencyPipeDecimalPipePercentPipeUpperCasePipe,LowerCasePipe, andTitleCasePipeJsonPipeAsyncPipe
UpperCasePipe
{{ product.name | uppercase }}
MacBook Pro becomes MACBOOK PRO.
LowerCasePipe
{{ email | lowercase }}
USER@EXAMPLE.COM becomes user@example.com.
TitleCasePipe
{{ 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.
{{ createdAt | date }}{{ createdAt | date:'short' }}{{ createdAt | date:'mediumDate' }}{{ createdAt | date:'dd/MM/yyyy' }}
Common Date Formats
{{ 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
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
{{ 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
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
{{ 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
{minIntegerDigits}.{minFractionDigits}-{maxFractionDigits}
Decimal formatting is useful for prices, measurements, ratings, financial displays, and statistical values.
PercentPipe
{{ discount | percent }}
If discount is 0.15, the output may be 15%. Remember that 1 represents 100%.
JsonPipe
<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.
products$ = this.productService.getProducts();
@if (products$ | async; as products) {@for (product of products; track product.id) {<p>{{ product.name }}</p>}}
AsyncPipe Architecture
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.
@if (products$ | async; as products) {<p>Total: {{ products.length }}</p>@for (product of products; track product.id) {{{ product.name }}}}
Passing Parameters to Pipes
{{ price | currency:'INR' }}{{ price | currency:'INR':'symbol':'1.2-2' }}
Pipe parameters use colons. Each parameter configures the transformation.
Chaining Pipes
{{ createdAt | date:'fullDate' | uppercase }}
The output of one Pipe becomes the input of the next Pipe.
Creating a Custom Pipe
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) + '...';}}
{{ description | truncate:100 }}
Custom Pipe Architecture
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.
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.
this.products.push(product3); // same array referencethis.products = [...this.products,product3]; // new array reference
This is one reason immutable update patterns work well with Angular's reactive architecture.
Impure Pipes
@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
@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.
searchTerm = signal('');products = signal<Product[]>([]);filteredProducts = computed(() => {const search = this.searchTerm().toLowerCase();return this.products().filter(product =>product.name.toLowerCase().includes(search));});
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
src/app/shared/└── pipes/├── truncate.pipe.ts├── file-size.pipe.ts└── highlight.pipe.tsfeatures/└── 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
<h2>{{ product.name | titlecase }}</h2><p>{{ product.price | currency:'INR' }}</p><p>Save {{ product.discount | percent }}</p><p>Added: {{ product.createdAt | date:'mediumDate' }}</p>
Product DTO│├── Name -> TitleCasePipe├── Price -> CurrencyPipe└── Date -> DatePipe│▼Product UI
Real-World Dashboard Example
<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.
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.
1BeginnerQuestionWhat is a Pipe in Angular?+
Answer
2BeginnerQuestionName some built-in Angular Pipes.+
Answer
3BeginnerQuestionWhat is AsyncPipe?+
Answer
4BeginnerQuestionWhat is the difference between pure and impure Pipes?+
Answer
5BeginnerQuestionAre Pipes pure by default?+
Answer
6IntermediateQuestionWhy might a pure Pipe not detect array.push()?+
Answer
7IntermediateQuestionWhy should we avoid expensive impure Pipes?+
Answer
8IntermediateQuestionWhat is the difference between a Pipe and a component method?+
Answer
9IntermediateQuestionWhat is the difference between a Pipe and a computed Signal?+
Answer
10IntermediateQuestionHow do you pass arguments to a Pipe?+
Answer
11AdvancedQuestionCan Pipes be chained?+
Answer
12AdvancedQuestionHow do you create a custom Pipe?+
Answer
13AdvancedQuestionShould filtering be implemented using a custom Pipe?+
Answer
14AdvancedQuestionCan multiple AsyncPipe usages cause multiple API calls?+
Answer
15AdvancedQuestionHow would you design Pipes in a large Angular application?+
Answer
Summary
Angular Pipes provide a clean way to transform raw application data into user-friendly presentation values.
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.