Skip to main content

Angular Currency Formatting

When building applications that display monetary values, proper currency formatting becomes essential for providing a good user experience. Angular provides powerful built-in tools to handle currency formatting across different locales and currencies. This guide will walk you through everything you need to know about formatting currencies in your Angular applications.

Introduction to Currency Formatting in Angular

Currency formatting involves displaying monetary values with the appropriate currency symbol, decimal places, and thousands separators according to the conventions of different locales. Angular's internationalization (i18n) features include the CurrencyPipe which makes this task straightforward.

The CurrencyPipe is part of Angular's Common module and allows you to:

  • Display the appropriate currency symbol
  • Format numbers according to locale-specific conventions
  • Control the number of decimal places
  • Specify the display style of the currency symbol

Basic Currency Formatting

Using the Currency Pipe

The simplest way to format a currency value in Angular is by using the built-in currency pipe in your templates.

html
<p>Price: {{ 42.5 | currency }}</p>

Output:

Price: $42.50

By default, the currency pipe uses USD as the currency code and displays the currency symbol.

Specifying a Currency Code

You can specify a different currency by passing the ISO 4217 currency code as the first parameter:

html
<p>Price in USD: {{ 42.5 | currency:'USD' }}</p>
<p>Price in EUR: {{ 42.5 | currency:'EUR' }}</p>
<p>Price in GBP: {{ 42.5 | currency:'GBP' }}</p>
<p>Price in JPY: {{ 42.5 | currency:'JPY' }}</p>

Output:

Price in USD: $42.50
Price in EUR: €42.50
Price in GBP: £42.50
Price in JPY: ¥43

Notice that JPY doesn't show decimal places by default since Japanese yen typically doesn't use fractional values.

Advanced Currency Formatting Options

Display Options

The currency pipe accepts a second parameter that controls how the currency symbol is displayed:

html
<!-- code: 'CAD' -->
<p>{{ 52.25 | currency:'CAD':'code' }}</p> <!-- CAD52.25 -->

<!-- symbol: '€' (default) -->
<p>{{ 52.25 | currency:'EUR':'symbol' }}</p> <!-- €52.25 -->

<!-- symbol-narrow: just the symbol -->
<p>{{ 52.25 | currency:'USD':'symbol-narrow' }}</p> <!-- $52.25 -->

<!-- String template with the currency symbol -->
<p>{{ 52.25 | currency:'USD':'Canadian $' }}</p> <!-- Canadian $52.25 -->

Digit Control

The third parameter allows you to control the number of decimal places:

html
<!-- Display with default digits (usually 2) -->
<p>{{ 42.1 | currency:'USD':'symbol' }}</p> <!-- $42.10 -->

<!-- Display with 3 decimal places -->
<p>{{ 42.1 | currency:'USD':'symbol':'1.3-3' }}</p> <!-- $42.100 -->

<!-- Display with minimum 1 digit and maximum 2 digits -->
<p>{{ 42.1 | currency:'USD':'symbol':'1.1-2' }}</p> <!-- $42.1 -->

<!-- Display as integer -->
<p>{{ 42.1 | currency:'USD':'symbol':'1.0-0' }}</p> <!-- $42 -->

The digit format string follows the pattern {minIntegerDigits}.{minFractionDigits}-{maxFractionDigits}.

Locale-Specific Formatting

Angular's currency pipe automatically adapts to the current locale. To change the locale for your application or component:

typescript
import { LOCALE_ID } from '@angular/core';

@NgModule({
// ...
providers: [
{ provide: LOCALE_ID, useValue: 'fr' } // Set locale to French
]
})
export class AppModule { }

Then register the locale data:

typescript
// In your main.ts or app.module.ts
import { registerLocaleData } from '@angular/common';
import localeFr from '@angular/common/locales/fr';

registerLocaleData(localeFr, 'fr');

Now currency values will be formatted according to French conventions:

html
<p>{{ 1234.56 | currency:'EUR' }}</p>

Output:

1 234,56 €

Notice that in French locale, the currency symbol appears after the amount, and a space is used as thousands separator instead of a comma.

Practical Examples

Product Catalog

Here's how you might display products with different currencies:

typescript
// product.component.ts
@Component({
selector: 'app-product',
template: `
<div class="product-card">
<h3>{{ product.name }}</h3>
<p class="price">{{ product.price | currency:product.currency }}</p>
<button>Add to Cart</button>
</div>
`
})
export class ProductComponent {
@Input() product: {
name: string;
price: number;
currency: string;
};
}

Multi-Currency Support

For applications that need to support multiple currencies:

typescript
// price-display.component.ts
@Component({
selector: 'app-price-display',
template: `
<div class="price-display">
<p>Original: {{ amount | currency:baseCurrency }}</p>
<p *ngFor="let curr of availableCurrencies">
{{ curr }}: {{ convert(amount, baseCurrency, curr) | currency:curr }}
</p>
<label>
Display Currency:
<select [(ngModel)]="selectedCurrency">
<option *ngFor="let curr of availableCurrencies" [value]="curr">{{ curr }}</option>
</select>
</label>
<p class="selected-price">
Selected Price: {{ convert(amount, baseCurrency, selectedCurrency) | currency:selectedCurrency }}
</p>
</div>
`
})
export class PriceDisplayComponent {
@Input() amount: number;
@Input() baseCurrency = 'USD';

availableCurrencies = ['USD', 'EUR', 'GBP', 'JPY'];
selectedCurrency = 'USD';

// In a real app, you'd use a service with actual exchange rates
convert(amount: number, from: string, to: string): number {
const rates = {
'USD': 1,
'EUR': 0.85,
'GBP': 0.73,
'JPY': 110.14
};

return amount * rates[to] / rates[from];
}
}

Shopping Cart Total

Here's how you might display a shopping cart total with tax and shipping:

typescript
// cart-total.component.ts
@Component({
selector: 'app-cart-total',
template: `
<div class="cart-summary">
<h3>Order Summary</h3>
<div class="line-item">
<span>Subtotal:</span>
<span>{{ subtotal | currency:currencyCode }}</span>
</div>
<div class="line-item">
<span>Tax ({{ taxRate * 100 }}%):</span>
<span>{{ subtotal * taxRate | currency:currencyCode }}</span>
</div>
<div class="line-item">
<span>Shipping:</span>
<span>{{ shipping | currency:currencyCode }}</span>
</div>
<div class="line-item total">
<span>Total:</span>
<span>{{ calculateTotal() | currency:currencyCode }}</span>
</div>
</div>
`,
styles: [`
.line-item {
display: flex;
justify-content: space-between;
margin-bottom: 8px;
}
.total {
font-weight: bold;
font-size: 1.2em;
border-top: 1px solid #ccc;
padding-top: 8px;
}
`]
})
export class CartTotalComponent {
@Input() subtotal = 0;
@Input() shipping = 0;
@Input() taxRate = 0.08;
@Input() currencyCode = 'USD';

calculateTotal(): number {
return this.subtotal + (this.subtotal * this.taxRate) + this.shipping;
}
}

Programmatic Currency Formatting

Sometimes you need to format currency values in your component code rather than in the template:

typescript
import { formatCurrency, getCurrencySymbol } from '@angular/common';
import { Inject, LOCALE_ID } from '@angular/core';

@Component({
selector: 'app-programmatic-formatting',
template: `
<p>Formatted values:</p>
<ul>
<li>{{ formattedValue }}</li>
<li>{{ customFormatted }}</li>
</ul>
`
})
export class ProgrammaticFormattingComponent {
formattedValue: string;
customFormatted: string;

constructor(@Inject(LOCALE_ID) private locale: string) {
// Basic formatting
this.formattedValue = formatCurrency(1234.56, this.locale, '$');

// Custom formatting
const currencyCode = 'GBP';
const symbol = getCurrencySymbol(currencyCode, 'wide', this.locale);
this.customFormatted = `${symbol}1,234.56`;
}
}

Common Challenges and Solutions

Handling Zero and Negative Values

You might want to display zero or negative values differently:

typescript
@Component({
selector: 'app-special-formatting',
template: `
<p>Regular price: {{ price | currency }}</p>
<p>Sale price: {{ displayPrice(salePrice) }}</p>
<p>Change: {{ change | currency }}</p>
`
})
export class SpecialFormattingComponent {
price = 49.99;
salePrice = 0;
change = -5.25;

displayPrice(price: number): string {
if (price === 0) {
return 'Free!';
}
return `${price | currency}`;
}
}

Supporting Right-to-Left (RTL) Languages

For RTL languages like Arabic or Hebrew, use the appropriate locale and the application should handle the direction automatically:

typescript
// In your module
import { registerLocaleData } from '@angular/common';
import localeAr from '@angular/common/locales/ar';

registerLocaleData(localeAr, 'ar');

// In your component
@Component({
selector: 'app-rtl-example',
template: `
<div dir="rtl" lang="ar">
<p>السعر: {{ 1234.56 | currency:'SAR' }}</p>
</div>
`
})
export class RtlExampleComponent {}

Summary

Angular's currency formatting capabilities through the CurrencyPipe provide a powerful way to display monetary values according to various international standards. We've covered:

  • Basic currency formatting with the currency pipe
  • Specifying different currency codes
  • Controlling the display of currency symbols
  • Formatting digits and decimal places
  • Adapting to different locales
  • Programmatic formatting for more complex use cases
  • Handling special cases like zero, negative values, and RTL languages

These tools make it easy to create applications that properly display monetary values for users worldwide, enhancing the user experience and making your application truly international.

Additional Resources

Exercises

  1. Create a simple product list that displays prices in USD, EUR, and JPY.
  2. Implement a currency converter that allows users to convert between different currencies using real exchange rates from a public API.
  3. Build a shopping cart that allows users to switch the display currency while maintaining the original price in the base currency.
  4. Create a component that formats negative currency values in red and positive values in green.
  5. Implement a budgeting feature that shows expenses with different formatting than income.


If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)