Angular Pipes: The Magic Translators 🪄
The Story of Data Transformation
Imagine you have a magic translator friend who can take anything you say and make it sound exactly how you want. Say “1234.5” and they can say “one thousand two hundred thirty-four dollars and fifty cents” or “1,234.50” or even “January 1234”!
That’s exactly what Angular Pipes do!
Pipes are like magic helpers that transform your data into a format that’s easy for people to read. You give them raw data, and they give you beautiful, formatted output.
How Pipes Work
{{ yourData | pipeName }}
The | symbol is called a pipe. It takes what’s on the left and transforms it using the pipe on the right.
Think of it like a water pipe: data goes in one end, and something new comes out the other end!
graph TD A[Raw Data] --> B[| pipeName] B --> C[Formatted Output]
Built-in Pipes: Your Ready-to-Use Magic Helpers
Angular comes with several pipes already built for you. Let’s meet them!
📅 DatePipe: The Time Teller
What it does: Takes ugly date numbers and makes them pretty!
The Problem
Computers store dates like this: 2024-12-25T10:30:00
Yuck! Nobody wants to read that!
The Solution
{{ myDate | date }}
<!-- Shows: Dec 25, 2024 -->
{{ myDate | date:'short' }}
<!-- Shows: 12/25/24, 10:30 AM -->
{{ myDate | date:'fullDate' }}
<!-- Shows: Wednesday, December 25, 2024 -->
{{ myDate | date:'yyyy-MM-dd' }}
<!-- Shows: 2024-12-25 -->
Common Date Formats
| Format | Example Output |
|---|---|
'short' |
12/25/24, 10:30 AM |
'medium' |
Dec 25, 2024, 10:30:00 AM |
'long' |
December 25, 2024 at 10:30:00 AM |
'fullDate' |
Wednesday, December 25, 2024 |
'shortTime' |
10:30 AM |
Real-life example:
// In your component
birthday = new Date(2010, 5, 15);
<!-- In your template -->
<p>Born on: {{ birthday | date:'longDate' }}</p>
<!-- Shows: June 15, 2010 -->
💰 CurrencyPipe: The Money Maker
What it does: Turns plain numbers into proper money formats!
The Problem
You have 1234.5 but you want people to see $1,234.50
The Solution
{{ 1234.5 | currency }}
<!-- Shows: $1,234.50 (USD by default) -->
{{ 1234.5 | currency:'EUR' }}
<!-- Shows: €1,234.50 -->
{{ 1234.5 | currency:'GBP':'symbol' }}
<!-- Shows: £1,234.50 -->
{{ 999 | currency:'INR':'symbol':'1.0-0' }}
<!-- Shows: ₹999 (no decimals) -->
How It Works
{{ value | currency:'CODE':'display':'digits' }}
- CODE: Currency code (USD, EUR, GBP, INR)
- display: ‘symbol’ ($), ‘code’ (USD), or ‘symbol-narrow’
- digits:
min.min-maxdecimals
graph TD A[1234.567] --> B[currency:'USD'] B --> C["$1,234.57"]
🔢 NumberPipe (DecimalPipe): The Number Beautifier
What it does: Makes numbers look clean and organized!
The Problem
You have 1234.56789 but that’s too many decimals!
The Solution
{{ 1234.56789 | number }}
<!-- Shows: 1,234.568 -->
{{ 1234.56789 | number:'1.2-2' }}
<!-- Shows: 1,234.57 (2 decimals) -->
{{ 5 | number:'3.0-0' }}
<!-- Shows: 005 (padded with zeros) -->
{{ 0.25 | percent }}
<!-- Shows: 25% -->
The Magic Formula: 'minInt.minDec-maxDec'
| Part | Meaning |
|---|---|
minInt |
Minimum digits before decimal |
minDec |
Minimum digits after decimal |
maxDec |
Maximum digits after decimal |
Example Breakdown:
{{ 3.14159 | number:'2.1-3' }}
<!--
2 = at least 2 digits before (03)
1 = at least 1 after decimal
3 = max 3 after decimal
Shows: 03.142
-->
⏳ AsyncPipe: The Patient Waiter
What it does: Waits for data that takes time to arrive (like from the internet), then shows it!
The Story
Imagine ordering pizza. You can’t eat it the moment you order—you have to wait for it to arrive. AsyncPipe is like having a friend who waits at the door for your pizza and hands it to you the moment it arrives!
The Problem
// This is a Promise or Observable
// Data will arrive later!
userData$ = this.http.get('/api/user');
Without AsyncPipe, you’d need messy code to wait and display.
The Solution
<!-- AsyncPipe handles all the waiting! -->
<p>Hello, {{ userName$ | async }}</p>
<!-- With fallback -->
<p *ngIf="userData$ | async as user">
Welcome, {{ user.name }}!
</p>
Why AsyncPipe is Amazing
graph TD A[Observable/Promise] --> B[async pipe] B --> C{Data Ready?} C -->|No| D[Keep Waiting...] C -->|Yes| E[Show Data!] D --> C B --> F[Auto Unsubscribe!]
Three superpowers:
- Waits for data automatically
- Updates the view when data arrives
- Cleans up when component is destroyed (no memory leaks!)
// Component
import { Observable } from 'rxjs';
export class UserComponent {
user$: Observable<User>;
constructor(private userService: UserService) {
this.user$ = this.userService.getUser();
}
}
<!-- Template - so clean! -->
<div *ngIf="user$ | async as user">
<h2>{{ user.name }}</h2>
<p>{{ user.email }}</p>
</div>
🛠️ Custom Pipes: Build Your Own Magic!
Sometimes the built-in pipes aren’t enough. What if you want to reverse text? Add emojis? That’s where custom pipes come in!
Creating a Custom Pipe
Step 1: Generate the pipe
ng generate pipe reverse
Step 2: Write the transformation logic
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'reverse'
})
export class ReversePipe implements PipeTransform {
transform(value: string): string {
if (!value) return '';
return value.split('').reverse().join('');
}
}
Step 3: Use it in your template
{{ 'Hello World' | reverse }}
<!-- Shows: dlroW olleH -->
Custom Pipe with Parameters
@Pipe({ name: 'shorten' })
export class ShortenPipe implements PipeTransform {
transform(value: string, limit: number = 10): string {
if (value.length <= limit) return value;
return value.substring(0, limit) + '...';
}
}
{{ 'This is a very long sentence' | shorten:15 }}
<!-- Shows: This is a very... -->
graph TD A["'Hello World'"] --> B[reverse pipe] B --> C["'dlroW olleH'"]
⚡ Pure vs Impure Pipes: The Speed Secret
This is the secret sauce of Angular pipes!
Pure Pipes (Default)
Like a calculator with memory: It only recalculates when you give it a NEW number.
@Pipe({
name: 'double',
pure: true // This is the default!
})
export class DoublePipe implements PipeTransform {
transform(value: number): number {
console.log('Calculating...');
return value * 2;
}
}
When does it run?
- ✅ When the input VALUE changes
- ❌ NOT when array/object contents change (only reference)
// Changes reference - PIPE RUNS
this.numbers = [...this.numbers, 5];
// Changes content only - PIPE DOESN'T RUN
this.numbers.push(5);
Impure Pipes
Like a paranoid checker: It rechecks EVERY time anything changes on the page!
@Pipe({
name: 'filter',
pure: false // Makes it impure
})
export class FilterPipe implements PipeTransform {
transform(items: any[], searchText: string): any[] {
// Runs on EVERY change detection cycle!
return items.filter(item =>
item.name.includes(searchText)
);
}
}
The Trade-off
graph TD A[Pure Pipe] --> B[Fast!] A --> C[Only runs when<br>reference changes] D[Impure Pipe] --> E[Slower] D --> F[Runs on every<br>change detection] B --> G[Use for most cases] E --> H[Use only when needed]
| Feature | Pure Pipe | Impure Pipe |
|---|---|---|
| Speed | ⚡ Fast | 🐌 Slower |
| Runs when | Input reference changes | Every change detection |
| Best for | Numbers, strings, simple transforms | Filtering arrays, real-time updates |
| Default | ✅ Yes | ❌ No |
When to Use Impure Pipes
Only use impure pipes when you MUST detect changes inside arrays/objects:
@Pipe({
name: 'activeTasks',
pure: false
})
export class ActiveTasksPipe implements PipeTransform {
transform(tasks: Task[]): Task[] {
// Needs to detect when task.completed changes
return tasks.filter(t => !t.completed);
}
}
🎯 Chaining Pipes: Combo Moves!
You can use multiple pipes together!
{{ birthday | date:'fullDate' | uppercase }}
<!-- Shows: WEDNESDAY, DECEMBER 25, 2024 -->
{{ price | currency:'USD' | slice:0:10 }}
<!-- Shows first 10 characters of formatted price -->
graph LR A[Data] --> B[Pipe 1] B --> C[Pipe 2] C --> D[Pipe 3] D --> E[Final Output]
🌟 Quick Reference
| Pipe | What It Does | Example |
|---|---|---|
date |
Formats dates | {{ myDate | date:'short' }} |
currency |
Formats money | {{ 99.99 | currency:'USD' }} |
number |
Formats numbers | {{ 1234.5 | number:'1.2-2' }} |
async |
Unwraps Observables | {{ data$ | async }} |
uppercase |
MAKES CAPS | {{ 'hi' | uppercase }} |
lowercase |
makes lowercase | {{ 'HI' | lowercase }} |
percent |
Shows % | {{ 0.5 | percent }} |
json |
Pretty prints objects | {{ obj | json }} |
🎉 You Did It!
Now you understand Angular Pipes! You know:
- ✅ What pipes are (data transformers)
- ✅ How to use DatePipe, CurrencyPipe, and NumberPipe
- ✅ How AsyncPipe waits for data
- ✅ How to create your own custom pipes
- ✅ The difference between pure and impure pipes
Remember: Pipes are your magic translators. They take messy data and make it beautiful for your users!