Angular Pipes

Read one Angular interview question at a time, then flip for the complete explanation, example, and code.

0/90 Known filtered set
Level
Read Full Guide Question: 1 of 90

Angular Interview Questions · Angular Pipes Companion Article

Angular Pipes – Complete Practical Guide

Angular applications often receive data in a form that is correct for the application but not ideal for displaying directly to users. A date may arrive as a JavaScript Date object, a price may be stored as a number, or text may need a consistent case before it appears on the screen. Angular pipes solve this presentation problem. They transform values directly inside templates without forcing developers to write repetitive formatting logic inside component classes. For example, suppose a component contains this value:

TypeScript
price = 1250.5;

Instead of manually formatting it in TypeScript, Angular can format it directly in the template:

HTML
<p>{{ price | currency:'USD' }}</p>

The original price value remains unchanged. The pipe only changes how the value is displayed.

What Are Pipes in Angular?

A pipe is a reusable transformation that takes a value, processes it, and returns another value for display.

The basic syntax is:

HTML
{{ value | pipeName }}

For example:

HTML
<p>{{ username | uppercase }}</p>

If username contains:

Text
dattatray

the displayed result becomes:

Text
DATTATRAY

The component property itself is still dattatray.

Why Pipes Are Useful

Pipes are commonly used for:

  • formatting dates
  • displaying currency
  • formatting decimal numbers
  • displaying percentages
  • changing text case
  • reading asynchronous values
  • temporarily displaying objects as JSON
  • applying reusable custom transformations

They help keep presentation-related logic out of component classes.

Without a pipe, a component may contain many methods only for formatting values. With pipes, the template remains expressive and the formatting logic can be reused.

How a Pipe Works

A pipe can be understood as a simple transformation:

Text
Original Value
     |
     v
   Pipe
     |
     v
Formatted Value

For example:

Text
2500.5
  |
CurrencyPipe
  |
  v
$2,500.50

The important point is that pipes normally transform the displayed representation, not the original value stored by the application.

Pipe Operator

Angular uses the pipe character | between a value and a pipe.

HTML
{{ value | pipe }}

Example:

HTML
{{ name | uppercase }}

Multiple pipes can also be chained:

HTML
{{ name | lowercase | titlecase }}

Each pipe receives the output produced by the previous pipe.

Built-in Angular Pipes

Angular provides several built-in pipes for common display requirements.

Frequently used pipes include:

PipePurpose
DatePipeFormats dates and times
CurrencyPipeFormats currency values
DecimalPipeFormats decimal numbers
PercentPipeFormats percentage values
UpperCasePipeConverts text to uppercase
LowerCasePipeConverts text to lowercase
TitleCasePipeConverts text to title case
JsonPipeConverts values to JSON-style text
AsyncPipeReads values from Promises and Observables

These pipes remove the need to repeatedly implement common formatting operations.

DatePipe

DatePipe formats date and time values.

Consider:

TypeScript
today = new Date();

A basic template can use:

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

Angular converts the date into a readable format.

Common DatePipe Formats

Angular provides predefined format names.

HTML
{{ today | date:'short' }}
HTML
{{ today | date:'medium' }}
HTML
{{ today | date:'long' }}
HTML
{{ today | date:'full' }}

For date-only formatting:

HTML
{{ today | date:'shortDate' }}
HTML
{{ today | date:'mediumDate' }}
HTML
{{ today | date:'longDate' }}
HTML
{{ today | date:'fullDate' }}

For time:

HTML
{{ today | date:'shortTime' }}
HTML
{{ today | date:'mediumTime' }}

Custom Date Formats

Custom patterns can also be used.

HTML
{{ today | date:'dd/MM/yyyy' }}

Possible output:

Text
17/08/2026

Another example:

HTML
{{ today | date:'dd MMM yyyy' }}

Possible output:

Text
17 Aug 2026

Including time:

HTML
{{ today | date:'dd MMM yyyy, hh:mm a' }}

Possible output:

Text
17 Aug 2026, 10:30 AM

DatePipe with Time Zone

A timezone can be supplied as another pipe argument.

HTML
{{ today | date:'medium':'UTC' }}

This is useful when an application stores timestamps in one timezone but needs to present them using another timezone.

Where DatePipe Is Commonly Used

Typical examples include:

  • order dates
  • employee joining dates
  • transaction timestamps
  • blog publication dates
  • appointment times
  • account creation dates
  • audit records

Keeping the raw timestamp in the data layer and formatting it only when displaying it is generally cleaner than storing already formatted date strings.

CurrencyPipe

CurrencyPipe converts a number into a localized currency representation.

Consider:

TypeScript
price = 1250.5;

Template:

HTML
{{ price | currency }}

A currency code can be supplied explicitly:

HTML
{{ price | currency:'USD' }}

Possible output:

Text
$1,250.50

Indian rupees:

HTML
{{ price | currency:'INR' }}

Possible output:

Text
₹1,250.50

Euro:

HTML
{{ price | currency:'EUR' }}

Display Currency Code Instead of Symbol

The display option can be changed.

HTML
{{ price | currency:'USD':'code' }}

This can display a value using the currency code rather than only its symbol.

A symbol can be requested with:

HTML
{{ price | currency:'USD':'symbol' }}

Controlling Currency Decimal Digits

The digit formatting argument can control minimum and maximum decimal places.

HTML
{{ price | currency:'USD':'symbol':'1.2-2' }}

The general pattern is:

Text
minimumIntegerDigits.minimumFractionDigits-maximumFractionDigits

For example:

Text
1.2-2

means:

  • at least 1 integer digit
  • at least 2 decimal digits
  • at most 2 decimal digits

Practical CurrencyPipe Example

TypeScript
product = {
  name: 'Laptop',
  price: 65999
};
HTML
<h3>{{ product.name }}</h3>
<p>Price: {{ product.price | currency:'INR' }}</p>

This is much cleaner than manually adding currency symbols and decimal formatting throughout the application.

DecimalPipe

DecimalPipe formats ordinary numeric values.

Suppose:

TypeScript
value = 12345.6789;

Template:

HTML
{{ value | number }}

Angular can apply locale-aware thousands separators and decimal formatting.

Controlling Decimal Places

HTML
{{ value | number:'1.2-2' }}

The format follows:

Text
minimumIntegerDigits.minimumFractionDigits-maximumFractionDigits

Example:

HTML
{{ 12.34567 | number:'1.2-3' }}

The result keeps at least two and at most three fraction digits.

Practical Uses of DecimalPipe

DecimalPipe is useful for displaying:

  • measurements
  • averages
  • financial statistics that are not currency
  • distances
  • ratings
  • calculated values
  • percentages stored as ordinary numbers
  • dashboard metrics

PercentPipe

PercentPipe converts a numeric value into percentage format.

For example:

TypeScript
completion = 0.75;

Template:

HTML
{{ completion | percent }}

Possible result:

Text
75%

This is important because the value 0.75 represents 75 percent.

Controlling Percentage Decimals

HTML
{{ completion | percent:'1.0-2' }}

This controls the number of decimal digits displayed.

For example:

HTML
{{ 0.7565 | percent:'1.2-2' }}

may be displayed as:

Text
75.65%

Common PercentPipe Mistake

Consider:

TypeScript
percentage = 75;

Then:

HTML
{{ percentage | percent }}

does not mean "display 75%". PercentPipe treats 1 as 100%, so a value of 75 represents 7500%.

When data already stores percentage points such as 75, convert it appropriately before applying PercentPipe, or display it according to the application's data model.

UpperCasePipe

UpperCasePipe converts text to uppercase.

TypeScript
technology = 'Angular';
HTML
{{ technology | uppercase }}

Output:

Text
ANGULAR

It is useful when a design requires uppercase presentation but the original data should remain unchanged.

LowerCasePipe

LowerCasePipe converts text to lowercase.

HTML
{{ 'ANGULAR DEVELOPMENT' | lowercase }}

Output:

Text
angular development

It can be useful when presenting normalized text such as tags, usernames, or labels.

However, formatting data using CSS may sometimes be more appropriate if the requirement is purely visual. Pipes should be used when Angular's transformed value is part of the desired template output.

TitleCasePipe

TitleCasePipe converts words into title-style capitalization.

HTML
{{ 'angular web development' | titlecase }}

Output:

Text
Angular Web Development

This can be useful for:

  • headings
  • labels
  • category names
  • user-facing titles
  • automatically generated menu text

Example:

TypeScript
courseName = 'complete angular interview preparation';
HTML
<h2>{{ courseName | titlecase }}</h2>

JsonPipe

JsonPipe converts an object into a JSON-style string.

Suppose the component contains:

TypeScript
user = {
  id: 101,
  name: 'Rahul',
  role: 'Developer'
};

Template:

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

This makes the object's structure easy to inspect.

Why JsonPipe Is Useful During Development

Without JsonPipe, writing:

HTML
{{ user }}

does not provide a useful representation of a complex object.

Using:

HTML
{{ user | json }}

helps developers inspect:

  • API responses
  • form values
  • nested objects
  • debugging data
  • component state

JsonPipe Is Mainly a Development Tool

JsonPipe is useful for inspection and debugging, but it is usually not the best choice for presenting application data to end users.

For example, instead of displaying:

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

a production UI would normally display specific properties:

HTML
<p>Name: {{ user.name }}</p>
<p>Role: {{ user.role }}</p>

This gives users a clearer interface.

AsyncPipe

AsyncPipe is one of the most useful Angular pipes when working with asynchronous data.

It can work with values such as:

  • Observable
  • Promise

Suppose a component has:

TypeScript
userName$ = of('Amit');

The template can use:

HTML
{{ userName$ | async }}

The AsyncPipe subscribes to the Observable and displays the emitted value.

Without AsyncPipe

Developers can manually subscribe:

TypeScript
this.userName$.subscribe(value => {
  this.userName = value;
});

This may also require subscription cleanup depending on how the subscription is managed.

With AsyncPipe

The template can consume the Observable directly:

HTML
<p>{{ userName$ | async }}</p>

AsyncPipe handles the subscription lifecycle for the template.

When the component is destroyed, Angular cleans up the subscription managed by the pipe.

AsyncPipe with an Object

Suppose:

TypeScript
user$ = this.userService.getUser();

A template may use modern Angular control flow:

HTML
@if (user$ | async; as user) {
  <h3>{{ user.name }}</h3>
  <p>{{ user.email }}</p>
}

This is often preferable to applying async repeatedly to the same Observable.

Avoid Repeated AsyncPipe Usage When Possible

Instead of:

HTML
<p>{{ (user$ | async)?.name }}</p>
<p>{{ (user$ | async)?.email }}</p>
<p>{{ (user$ | async)?.role }}</p>

capture the resolved value once:

HTML
@if (user$ | async; as user) {
  <p>{{ user.name }}</p>
  <p>{{ user.email }}</p>
  <p>{{ user.role }}</p>
}

This also makes the template easier to read.

AsyncPipe and Signals

AsyncPipe is designed for asynchronous primitives such as Observables and Promises.

Angular signals are read directly:

HTML
{{ username() }}

They do not normally require:

HTML
{{ username | async }}

Understanding this distinction is useful when working with modern Angular applications that combine RxJS and signals.

Pipe Arguments

Many pipes accept additional values called arguments or parameters.

Arguments are separated using colons.

Basic syntax:

HTML
{{ value | pipeName:argument1:argument2 }}

Example:

HTML
{{ amount | currency:'INR':'symbol' }}

Here:

  • amount is the input value
  • currency is the pipe
  • 'INR' is the first argument
  • 'symbol' is the second argument

Another example:

HTML
{{ today | date:'dd/MM/yyyy':'UTC' }}

Arguments allow one pipe to support many formatting requirements.

Chaining Multiple Pipes

Angular allows multiple pipes to be applied sequentially.

HTML
{{ value | pipe1 | pipe2 }}

Example:

HTML
{{ 'angular PIPE example' | lowercase | titlecase }}

Processing occurs from left to right.

First:

Text
angular PIPE example

becomes:

Text
angular pipe example

Then TitleCasePipe produces:

Text
Angular Pipe Example

Pipe chaining should be used when each transformation has a clear purpose. Excessive chaining can make a template difficult to understand.

Custom Pipes

Built-in pipes solve common formatting requirements, but applications frequently need business-specific transformations.

Angular allows developers to create custom pipes.

Examples include:

  • converting file sizes into KB or MB
  • shortening long text
  • masking sensitive values
  • displaying custom status labels
  • transforming product codes
  • formatting application-specific IDs
  • calculating user-friendly durations

Basic Custom Pipe Structure

A custom pipe typically uses:

  • @Pipe
  • PipeTransform
  • a transform() method

Example:

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

@Pipe({
  name: 'reverseText'
})
export class ReverseTextPipe implements PipeTransform {

  transform(value: string): string {
    return value.split('').reverse().join('');
  }
}

Template:

HTML
{{ 'Angular' | reverseText }}

Output:

Text
ralugnA

The transform() method contains the transformation logic.

Custom Pipe with Arguments

A custom pipe can accept arguments after the input value.

Example:

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

@Pipe({
  name: 'shortText'
})
export class ShortTextPipe implements PipeTransform {

  transform(value: string, limit: number = 20): string {
    if (!value) {
      return '';
    }

    return value.length > limit
      ? value.substring(0, limit) + '...'
      : value;
  }
}

Template:

HTML
{{ description | shortText:50 }}

Here:

  • description is the input
  • shortText is the pipe
  • 50 is the pipe argument

This approach makes the pipe reusable with different limits.

Standalone Custom Pipes

In modern Angular applications, a pipe can be standalone.

Example:

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

@Pipe({
  name: 'fileSize',
  standalone: true
})
export class FileSizePipe implements PipeTransform {

  transform(bytes: number): string {
    if (bytes < 1024) {
      return `${bytes} B`;
    }

    return `${(bytes / 1024).toFixed(2)} KB`;
  }
}

A standalone component can import the pipe:

TypeScript
@Component({
  selector: 'app-file',
  standalone: true,
  imports: [FileSizePipe],
  template: `
    <p>{{ fileSize | fileSize }}</p>
  `
})
export class FileComponent {
  fileSize = 4096;
}

This makes the pipe directly available to that component's template.

Pure Pipes

Angular pipes are pure by default.

A pure pipe executes when Angular detects a meaningful change to its input.

For primitive values, this includes changes such as:

Text
10 → 20

or:

Text
Angular → React

For objects and arrays, reference changes are especially important.

Pure Pipe Example

TypeScript
@Pipe({
  name: 'customFormat',
  pure: true
})
export class CustomFormatPipe implements PipeTransform {
  transform(value: string): string {
    return value.toUpperCase();
  }
}

Because pure: true is the default, it normally does not need to be specified explicitly.

This is enough:

TypeScript
@Pipe({
  name: 'customFormat'
})

Object Mutation and Pure Pipes

Consider:

TypeScript
users = [
  { name: 'Amit' },
  { name: 'Rahul' }
];

If the same array is mutated:

TypeScript
this.users.push({ name: 'Neha' });

a pure pipe that receives users may not execute just because the internal contents changed, since the array reference can remain the same.

Creating a new array reference makes the change explicit:

TypeScript
this.users = [
  ...this.users,
  { name: 'Neha' }
];

This distinction is important when designing custom pipes for arrays and objects.

Impure Pipes

An impure pipe is created using:

TypeScript
@Pipe({
  name: 'filterUsers',
  pure: false
})

Angular can execute an impure pipe much more frequently during change detection.

This means an impure pipe can notice changes inside mutable objects or arrays, but that flexibility has a performance cost.

Example of an Impure Pipe

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

@Pipe({
  name: 'activeUsers',
  pure: false
})
export class ActiveUsersPipe implements PipeTransform {

  transform(users: any[]): any[] {
    return users.filter(user => user.active);
  }
}

Template:

HTML
@for (user of users | activeUsers; track user.id) {
  <p>{{ user.name }}</p>
}

This may work, but Angular may invoke the transformation frequently.

For a large list or expensive calculation, this can create unnecessary processing.

Pure Pipes vs Impure Pipes

FeaturePure PipeImpure Pipe
Default Angular behaviorYesNo
Configurationpure: truepure: false
PerformanceUsually betterCan be expensive
Detects primitive input changesYesYes
Designed for frequent mutable-content checksNoCan react to them
Recommended for normal transformationsYesOnly when justified
Can execute frequently during change detectionLess oftenYes

Pure pipes should normally be preferred.

Impure pipes should be introduced only when the behavior is genuinely required and its performance impact is understood.

Why Expensive Logic Should Not Be Placed in Pipes

A pipe may be evaluated as part of Angular's template update process.

Therefore, expensive work such as:

  • large data processing
  • complicated sorting
  • network requests
  • database operations
  • unnecessary object creation
  • CPU-heavy calculations

should not be casually placed inside a pipe.

For example, this would be a poor design for a frequently evaluated pipe:

TypeScript
transform(items: Product[]): Product[] {
  return items
    .filter(...)
    .sort(...)
    .map(...)
    .filter(...);
}

if thousands of items are processed repeatedly.

For complex business transformations, consider handling the operation before the data reaches the template.

Pipes Should Not Be Used for Side Effects

A pipe should ideally behave like a transformation:

Text
Input → Transformation → Output

It should not normally:

  • modify global application state
  • update another component
  • send HTTP requests
  • write to storage
  • trigger navigation
  • change the original input unexpectedly

Predictable pipes are easier to test, reuse, and maintain.

Do Not Modify Input Objects Inside a Pipe

Avoid code such as:

TypeScript
transform(user: User): User {
  user.name = user.name.toUpperCase();
  return user;
}

The pipe is modifying the original object.

A safer transformation returns the required output without mutating the input:

TypeScript
transform(user: User): string {
  return user.name.toUpperCase();
}

For object transformations, create a new object when appropriate rather than unexpectedly modifying the existing one.

Handling Null or Undefined Values

Real applications often receive incomplete data.

A custom pipe should consider values such as:

Text
null
undefined
''

Example:

TypeScript
transform(value: string | null | undefined): string {
  if (!value) {
    return 'Not Available';
  }

  return value.toUpperCase();
}

Defensive handling makes custom pipes safer when consuming API data.

Practical Custom Pipe: File Size Formatter

A backend may return:

Text
1536000

Displaying that raw byte count is not very user friendly.

A custom pipe can convert it.

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

@Pipe({
  name: 'fileSize',
  standalone: true
})
export class FileSizePipe implements PipeTransform {

  transform(bytes: number): string {
    if (!Number.isFinite(bytes) || bytes < 0) {
      return 'Invalid size';
    }

    if (bytes < 1024) {
      return `${bytes} B`;
    }

    if (bytes < 1024 * 1024) {
      return `${(bytes / 1024).toFixed(2)} KB`;
    }

    return `${(bytes / (1024 * 1024)).toFixed(2)} MB`;
  }
}

Template:

HTML
<p>File Size: {{ attachment.size | fileSize }}</p>

This is a good use of a custom pipe because the transformation is:

  • presentation-focused
  • reusable
  • predictable
  • easy to test

Practical Custom Pipe: Masking a Value

Suppose a UI should display only the final four digits of an account number.

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

@Pipe({
  name: 'maskAccount',
  standalone: true
})
export class MaskAccountPipe implements PipeTransform {

  transform(value: string): string {
    if (!value || value.length <= 4) {
      return value;
    }

    return '*'.repeat(value.length - 4) + value.slice(-4);
  }
}

Template:

HTML
{{ accountNumber | maskAccount }}

Possible result:

Text
********5678

Remember that UI masking is a presentation technique. It is not a substitute for proper security, authorization, and protection of sensitive data.

Built-in Pipe Imports in Standalone Components

In standalone Angular components, built-in pipes can be imported when needed.

Example:

TypeScript
import { Component } from '@angular/core';
import { CurrencyPipe, DatePipe } from '@angular/common';

@Component({
  selector: 'app-order',
  standalone: true,
  imports: [CurrencyPipe, DatePipe],
  template: `
    <p>{{ orderDate | date:'mediumDate' }}</p>
    <p>{{ total | currency:'INR' }}</p>
  `
})
export class OrderComponent {
  orderDate = new Date();
  total = 4999;
}

Import only the template features that the component actually needs.

Pipes and Localization

Several Angular formatting pipes are locale-aware.

Examples include:

  • DatePipe
  • CurrencyPipe
  • DecimalPipe
  • PercentPipe

This is important for international applications because countries may use different:

  • date formats
  • number separators
  • decimal separators
  • currency conventions

For example, blindly creating strings such as:

TypeScript
'$' + price.toFixed(2)

does not provide the same localization support as Angular's formatting infrastructure.

Pipe Arguments vs Component Methods

Suppose a template repeatedly calls:

HTML
{{ formatCurrency(product.price) }}

A component method may execute frequently as Angular updates the view.

For reusable presentation transformations, a pure pipe can often communicate the intention more clearly:

HTML
{{ product.price | currency:'INR' }}

However, not every function should automatically become a pipe. Choose according to responsibility:

  • reusable display transformation → pipe
  • business rule → service or domain logic
  • component-specific action → component logic
  • reusable data processing → appropriate service/helper/computed state

Pipes vs CSS

Suppose text needs to visually appear in uppercase.

Angular can do:

HTML
{{ name | uppercase }}

CSS can also do:

CSS
.name {
  text-transform: uppercase;
}

These are not identical design decisions.

Use CSS when uppercase is purely visual styling.

Use a pipe when the transformed textual value is intentionally part of Angular's template output.

Choosing the correct layer keeps application responsibilities clear.

Pipes vs Services

Pipes and services solve different problems.

Pipe

Best suited to reusable display transformations.

Text
1250 → ₹1,250.00

Service

Better suited to application or business operations such as:

  • API communication
  • data retrieval
  • authorization
  • shared business calculations
  • application state
  • reusable workflows

A pipe should not become a replacement for a service.

Common Mistakes with Angular Pipes

Performing Heavy Calculations in Impure Pipes

Impure pipes may run frequently, so expensive transformations can affect UI performance.

Mutating Arrays with Pure Pipes

Changing an array internally without changing its reference can prevent a pure pipe from producing an updated result when expected.

Using Pipes for Business Logic

Pipes are best for presentation transformations, not major application workflows.

Making HTTP Requests from Pipes

Network calls should normally be handled through services rather than triggered by template transformations.

Repeatedly Applying AsyncPipe to the Same Value

Capture an asynchronous result once when multiple properties are required.

Assuming PercentPipe Accepts 75 as 75%

Remember that:

Text
0.75 → 75%

Using JsonPipe as Final User Interface

JsonPipe is excellent for debugging but normally not appropriate as a user-friendly production display.

Forgetting Null Values

Custom pipes should safely handle missing values when application data can be incomplete.

Creating a Pipe for Every Tiny Requirement

Not every formatting problem requires a custom pipe. Built-in pipes, CSS, component state, computed values, or plain template expressions may already solve the problem.

Good Practices for Angular Pipes

Follow these guidelines when designing pipes:

  • Prefer built-in Angular pipes when they already solve the requirement.
  • Keep custom pipes focused on one responsibility.
  • Prefer pure pipes unless an impure pipe is genuinely necessary.
  • Keep transformations predictable.
  • Avoid modifying the original input.
  • Handle null and undefined where appropriate.
  • Avoid network requests and side effects.
  • Keep expensive calculations away from frequently evaluated pipes.
  • Give custom pipes clear and meaningful names.
  • Make reusable pipes independent from individual components.
  • Test custom transformation logic independently.
  • Use locale-aware pipes for user-facing numbers, currencies, and dates.
  • Use AsyncPipe when template code directly consumes suitable Observables or Promises.

When Should You Create a Custom Pipe?

A custom pipe is a good choice when all or most of the following are true:

  • the same transformation is required in multiple templates
  • the transformation is mainly presentation-related
  • the transformation can be expressed as input → output
  • the logic does not require side effects
  • the logic is easy to test independently
  • built-in Angular pipes do not already solve the problem

For example, an application that repeatedly displays file sizes would benefit from:

HTML
{{ file.size | fileSize }}

instead of repeating formatting logic in every component.

Real-World Angular Pipes Example

Consider an order dashboard containing:

TypeScript
order = {
  customerName: 'rahul patil',
  orderDate: new Date(),
  total: 15499.5,
  discountRate: 0.1,
  status: 'confirmed'
};

The template can use several pipes:

HTML
<h2>{{ order.customerName | titlecase }}</h2>

<p>
  Order Date:
  {{ order.orderDate | date:'dd MMM yyyy' }}
</p>

<p>
  Total:
  {{ order.total | currency:'INR' }}
</p>

<p>
  Discount:
  {{ order.discountRate | percent }}
</p>

<p>
  Status:
  {{ order.status | uppercase }}
</p>

The underlying data remains suitable for calculations and application logic, while the UI receives readable formatted output.

This separation is one of the main reasons pipes are valuable in Angular applications.

Quick Pipe Reference

RequirementExample
Uppercase text`{{ name \uppercase }}`
Lowercase text`{{ name \lowercase }}`
Title case`{{ title \titlecase }}`
Format date`{{ date \date:'dd/MM/yyyy' }}`
Indian currency`{{ price \currency:'INR' }}`
US currency`{{ price \currency:'USD' }}`
Format decimal`{{ value \number:'1.2-2' }}`
Format percentage`{{ rate \percent }}`
Inspect an object`{{ object \json }}`
Read Observable/Promise`{{ data$ \async }}`
Pass pipe argument`{{ value \pipeName:argument }}`
Chain pipes`{{ text \lowercase \titlecase }}`

Frequently Asked Questions About Angular Pipes

What is a pipe in Angular?

A pipe transforms a value for presentation inside an Angular template. It is commonly used for dates, currency, numbers, percentages, text formatting, and asynchronous values.

Does a pipe change the original component value?

Normally, no. A pipe receives the value and returns a transformed representation. Well-designed pipes should avoid unexpectedly mutating the original data.

What symbol is used for pipes?

Angular uses the | pipe operator.

HTML
{{ value | pipeName }}

Can one value use multiple pipes?

Yes.

HTML
{{ name | lowercase | titlecase }}

Pipes are processed from left to right.

How are arguments passed to a pipe?

Arguments are separated using colons.

HTML
{{ value | pipeName:arg1:arg2 }}

What is a pure pipe?

A pure pipe is Angular's normal/default pipe behavior. It is evaluated when Angular detects relevant input changes rather than being intentionally executed for mutable internal changes on every detection cycle.

What is an impure pipe?

An impure pipe uses:

TypeScript
pure: false

It can execute frequently during change detection and therefore should be used carefully.

Are Angular pipes pure by default?

Yes. Custom Angular pipes are pure by default unless pure: false is configured.

Which is better: pure or impure pipe?

Pure pipes are generally preferred because they offer more predictable and efficient behavior. Impure pipes are appropriate only for specific situations.

What does AsyncPipe do?

AsyncPipe reads values from supported asynchronous sources such as Observables and Promises and updates the template when new values become available.

Does AsyncPipe unsubscribe automatically?

For subscriptions it manages, Angular cleans them up when the associated view is destroyed or when the asynchronous source changes.

Is AsyncPipe required for Angular signals?

No. Signals are normally read directly in templates by calling them, such as:

HTML
{{ username() }}

What is JsonPipe mainly used for?

It is particularly useful during development for inspecting objects, API results, forms, and component state.

Can pipes be used inside property bindings?

Yes. A pipe can participate in template expressions used in bindings where Angular's template syntax permits it.

For example:

HTML
<input [value]="username | uppercase">

Can a custom pipe accept multiple arguments?

Yes.

Conceptually:

HTML
{{ value | customPipe:arg1:arg2:arg3 }}

The corresponding transform() method receives those arguments after the input value.

Should an HTTP request be made inside a pipe?

Normally, no. HTTP communication belongs in services or another appropriate data layer. Pipes should remain predictable transformations.

Can a pipe modify an array?

Technically code can mutate objects, but doing so inside a pipe is generally poor design. A pipe should preferably return a transformed result without unexpectedly modifying its input.

Why might a pure pipe not update after array.push()?

push() modifies the existing array rather than creating a new array reference. Pure pipe behavior is designed around changes to its input values/references rather than deep inspection of every mutable object.

A new reference can be created with:

TypeScript
this.items = [...this.items, newItem];

Should filtering a large list be done using an impure pipe?

Usually not automatically. Repeated filtering of large collections during change detection can become expensive. Consider preparing or deriving the filtered data outside an impure template pipe.

When should I create a custom pipe instead of a component method?

A custom pipe is useful when the transformation is reusable, presentation-focused, deterministic, and used from templates. Component-specific behavior may remain in the component.

Are pipes only used for strings?

No. Pipes can process many types of values including:

  • strings
  • numbers
  • dates
  • arrays
  • objects
  • Observables
  • Promises

The accepted input depends on the individual pipe.

Can pipes return objects or arrays?

Yes. A custom pipe's transform() method can return any appropriate type. However, object and array transformations should be designed carefully with change detection and performance in mind.

Angular Pipes Interview Revision

Remember these core points:

  1. A pipe transforms data primarily for template presentation.
  2. Angular uses the | operator for pipes.
  3. Pipe arguments are separated using :.
  4. Multiple pipes can be chained.
  5. Angular provides built-in pipes for dates, numbers, currency, percentages, text, JSON, and asynchronous values.
  6. AsyncPipe is commonly used with Observables and Promises.
  7. Custom pipes implement reusable transformation logic.
  8. Custom pipes commonly implement PipeTransform.
  9. Transformation logic is placed inside transform().
  10. Pipes are pure by default.
  11. Pure pipes work best with immutable/reference-based data changes.
  12. Impure pipes use pure: false.
  13. Impure pipes can execute frequently and may affect performance.
  14. Pipes should normally avoid side effects.
  15. Heavy business logic and network operations do not belong inside presentation pipes.
  16. Built-in locale-aware pipes are preferable to manually constructing formatted date, number, or currency strings.
  17. Custom pipes should handle invalid or missing input when such values are possible.
  18. A pipe is most valuable when a transformation is reusable, predictable, and presentation-focused.

Angular pipes are therefore more than template shortcuts. Used correctly, they provide a clean boundary between raw application data and the human-readable representation shown in the user interface.

Question Hint