Angular Number Formatting
Introduction
Number formatting is an essential aspect of developing applications with a global audience. Different regions around the world have varying conventions for displaying numbers, currencies, and percentages. Angular provides powerful built-in tools to handle these formatting needs through its internationalization (i18n) features.
In this guide, we'll explore Angular's number formatting capabilities, which allow you to display numbers in a way that's familiar and intuitive to users across different locales without writing complex formatting logic yourself.
Basic Number Formatting with DecimalPipe
Angular's DecimalPipe
is the foundation for number formatting. It transforms a number into a text string formatted according to locale rules.
Basic Syntax
{{ value_expression | number[:digitInfo] }}
Where:
value_expression
is the number you want to formatdigitInfo
is an optional parameter that specifies the format using the pattern:{minIntegerDigits}.{minFractionDigits}-{maxFractionDigits}
Simple Example
import { Component } from '@angular/core';
@Component({
selector: 'app-number-format-demo',
template: `
<h2>Basic Number Formatting</h2>
<p>Without formatting: {{ myNumber }}</p>
<p>With number pipe: {{ myNumber | number }}</p>
`
})
export class NumberFormatDemoComponent {
myNumber = 1234.5678;
}
Output:
Without formatting: 1234.5678
With number pipe: 1,234.568
By default, the number
pipe rounds to 3 decimal places and adds the thousand separator according to the current locale.
Controlling Decimal Places
You can control how many decimal places are displayed with the optional parameter:
@Component({
selector: 'app-decimal-format-demo',
template: `
<h2>Controlling Decimal Places</h2>
<p>{{ myNumber | number:'1.0-0' }}</p> <!-- At least 1 integer digit, 0 decimal places -->
<p>{{ myNumber | number:'1.1-1' }}</p> <!-- At least 1 integer digit, exactly 1 decimal place -->
<p>{{ myNumber | number:'1.2-2' }}</p> <!-- At least 1 integer digit, exactly 2 decimal places -->
<p>{{ myNumber | number:'1.1-5' }}</p> <!-- At least 1 integer digit, at least 1 but no more than 5 decimal places -->
`
})
export class DecimalFormatDemoComponent {
myNumber = 1234.5678;
}
Output:
1,235 <!-- Rounded to 0 decimal places -->
1,234.6 <!-- Rounded to 1 decimal place -->
1,234.57 <!-- Rounded to 2 decimal places -->
1,234.5678 <!-- Uses actual decimal places (4), within the 1-5 range -->
Currency Formatting with CurrencyPipe
For handling monetary values, Angular provides the CurrencyPipe
which not only formats the number but also adds the appropriate currency symbol.
Basic Syntax
{{ value_expression | currency[:currencyCode[:display[:digitInfo]]] }}
Where:
currencyCode
is the ISO 4217 currency code (e.g., 'USD', 'EUR')display
can be 'code', 'symbol', 'symbol-narrow', or 'name' (default is 'symbol')digitInfo
works the same as with thenumber
pipe
Currency Examples
@Component({
selector: 'app-currency-format-demo',
template: `
<h2>Currency Formatting</h2>
<p>{{ price | currency }}</p> <!-- Default: USD -->
<p>{{ price | currency:'EUR' }}</p> <!-- Euro with symbol -->
<p>{{ price | currency:'JPY':'code' }}</p> <!-- Japanese Yen with code -->
<p>{{ price | currency:'GBP':'symbol':'1.2-2' }}</p> <!-- British Pound with 2 decimal places -->
<p>{{ price | currency:'CAD':'symbol-narrow' }}</p> <!-- Canadian Dollar with narrow symbol -->
<p>{{ price | currency:'INR':'name' }}</p> <!-- Indian Rupee with name -->
`
})
export class CurrencyFormatDemoComponent {
price = 1234.5678;
}
Output (assuming en-US locale):
$1,234.57
€1,234.57
JPY 1,235
£1,234.57
$1,234.57
1,234.57 Indian rupees
Percentage Formatting with PercentPipe
For displaying percentages, Angular provides the PercentPipe
.
Basic Syntax
{{ value_expression | percent[:digitInfo] }}
Percentage Examples
@Component({
selector: 'app-percent-format-demo',
template: `
<h2>Percentage Formatting</h2>
<p>{{ 0.7654 | percent }}</p> <!-- Default formatting -->
<p>{{ 0.7654 | percent:'1.2-2' }}</p> <!-- With 2 decimal places -->
<p>{{ 0.7654 | percent:'2.3-3':'fr' }}</p> <!-- French locale with 3 decimal places -->
`
})
export class PercentFormatDemoComponent {
}
Output (assuming en-US locale unless specified):
77%
76.54%
76,540 % (with French formatting)
Working with Different Locales
Angular's number formatting adapts to different locales. You can specify the locale in two ways:
- Globally for the entire application
- Locally for specific formatting operations
Global Locale Configuration
In your app module, import LOCALE_ID
and provide it:
import { NgModule, LOCALE_ID } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
// Import locales you need to support
import { registerLocaleData } from '@angular/common';
import localeFr from '@angular/common/locales/fr';
import localeJa from '@angular/common/locales/ja';
// Register the locales
registerLocaleData(localeFr);
registerLocaleData(localeJa);
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule],
providers: [
// Set French as the default locale
{ provide: LOCALE_ID, useValue: 'fr' }
],
bootstrap: [AppComponent]
})
export class AppModule { }
Local Format Override
You can also override the locale for specific formatting operations:
@Component({
selector: 'app-locale-format-demo',
template: `
<h2>Locale-Specific Formatting</h2>
<p>US format: {{ myNumber | number:'1.1-1':'en-US' }}</p>
<p>German format: {{ myNumber | number:'1.1-1':'de' }}</p>
<p>Japanese format: {{ myNumber | number:'1.1-1':'ja-JP' }}</p>
<p>US currency: {{ myNumber | currency:'USD':'symbol':'1.2-2':'en-US' }}</p>
<p>Euro (German): {{ myNumber | currency:'EUR':'symbol':'1.2-2':'de' }}</p>
`
})
export class LocaleFormatDemoComponent {
myNumber = 1234567.89;
}
Output:
US format: 1,234,567.9
German format: 1.234.567,9
Japanese format: 1,234,567.9
US currency: $1,234,567.89
Euro (German): 1.234.567,89 €
Real-World Application: Dashboard with Financial Data
Let's see how number formatting can be applied in a real-world scenario, such as a financial dashboard component:
import { Component } from '@angular/core';
@Component({
selector: 'app-financial-dashboard',
template: `
<div class="dashboard">
<h2>Financial Dashboard</h2>
<div class="metric-card">
<span class="metric-title">Revenue</span>
<span class="metric-value">{{ revenueTotal | currency:'USD':'symbol':'1.0-0' }}</span>
<span class="metric-change" [class.positive]="revenueGrowth > 0" [class.negative]="revenueGrowth < 0">
{{ revenueGrowth | number:'1.1-1' }}%
</span>
</div>
<div class="metric-card">
<span class="metric-title">Conversion Rate</span>
<span class="metric-value">{{ conversionRate | percent:'1.2-2' }}</span>
</div>
<div class="metric-card">
<span class="metric-title">Avg Order Value</span>
<span class="metric-value">{{ avgOrderValue | currency:'USD' }}</span>
</div>
<h3>International Sales</h3>
<table class="sales-table">
<thead>
<tr>
<th>Region</th>
<th>Revenue</th>
<th>Growth</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let region of internationalSales">
<td>{{ region.name }}</td>
<td>{{ region.revenue | currency:region.currency:'symbol':'1.0-0':region.locale }}</td>
<td [class.positive]="region.growth > 0" [class.negative]="region.growth < 0">
{{ region.growth | number:'1.1-1' }}%
</td>
</tr>
</tbody>
</table>
</div>
`,
styles: [`
.metric-card {
padding: 15px;
margin-bottom: 10px;
border-radius: 4px;
background-color: #f5f5f5;
}
.metric-title {
display: block;
font-weight: bold;
}
.metric-value {
display: block;
font-size: 24px;
}
.positive { color: green; }
.negative { color: red; }
.sales-table {
width: 100%;
border-collapse: collapse;
}
.sales-table th, .sales-table td {
padding: 8px;
border-bottom: 1px solid #ddd;
text-align: left;
}
`]
})
export class FinancialDashboardComponent {
revenueTotal = 1254789.52;
revenueGrowth = 12.6;
conversionRate = 0.0324;
avgOrderValue = 68.42;
internationalSales = [
{ name: 'North America', revenue: 785432.21, growth: 8.7, currency: 'USD', locale: 'en-US' },
{ name: 'Europe', revenue: 645231.89, growth: 15.2, currency: 'EUR', locale: 'de' },
{ name: 'Japan', revenue: 432156.32, growth: -2.3, currency: 'JPY', locale: 'ja-JP' },
{ name: 'Australia', revenue: 145632.12, growth: 5.6, currency: 'AUD', locale: 'en-AU' }
];
}
This dashboard example demonstrates how number formatting can enhance the user experience by:
- Showing large revenue numbers without decimal places
- Displaying percentages with appropriate precision
- Using appropriate currency symbols for each region
- Formatting numbers according to local conventions
Summary
Angular's number formatting features provide a powerful way to display numeric data in user-friendly formats across different locales:
- DecimalPipe (
number
) formats general numeric values - CurrencyPipe (
currency
) formats monetary values with currency symbols - PercentPipe (
percent
) formats numbers as percentages
Key advantages include:
- Automatic locale-specific formatting
- Simple syntax for controlling precision
- Support for different display options for currencies
- Easy localization for global audiences
These pipes handle the complex logic of number formatting for you, helping you create applications that work seamlessly for users around the world.
Additional Resources and Exercises
Resources
Exercises
-
Product Catalog Exercise: Create a product catalog that displays prices in multiple currencies, allowing the user to switch between them.
-
Statistics Dashboard: Build a dashboard showing various statistics (average, percentage, totals) properly formatted with appropriate precision.
-
Locale Switcher: Create a component that allows users to change the locale of the application and see how number formats update accordingly.
-
Custom Formatting: Try to implement a custom pipe that extends the number formatting capabilities for a specialized use case (e.g., formatting file sizes from bytes to KB/MB/GB).
-
Financial Calculator: Build a loan or mortgage calculator that formats interest rates, monthly payments, and total amounts appropriately.
If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)