feat(common): allow default currency code to be configurable (#32584)
Default currency code in CurrencyPipe is currently hardcoded to USD and is not configurable. This commit allows the default currency code to be configurable by adding a DEFAULT_CURRENCY_CODE injection token. Example: ``` providers: [{ provide: DEFAULT_CURRENCY_CODE, useValue: "GBP" }] ... {{ 123.45 | currency }} // outputs £123.45 as opposed to always $123.45 before ``` Closes: #25461 PR Close #32584
This commit is contained in:
parent
cfbb1a1e77
commit
ca1bc7e80b
|
@ -6,11 +6,13 @@
|
||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {Inject, LOCALE_ID, Pipe, PipeTransform} from '@angular/core';
|
import {DEFAULT_CURRENCY_CODE, Inject, LOCALE_ID, Pipe, PipeTransform} from '@angular/core';
|
||||||
import {formatCurrency, formatNumber, formatPercent} from '../i18n/format_number';
|
import {formatCurrency, formatNumber, formatPercent} from '../i18n/format_number';
|
||||||
import {getCurrencySymbol} from '../i18n/locale_data_api';
|
import {getCurrencySymbol} from '../i18n/locale_data_api';
|
||||||
|
|
||||||
import {invalidPipeArgumentError} from './invalid_pipe_argument_error';
|
import {invalidPipeArgumentError} from './invalid_pipe_argument_error';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ngModule CommonModule
|
* @ngModule CommonModule
|
||||||
* @description
|
* @description
|
||||||
|
@ -155,13 +157,16 @@ export class PercentPipe implements PipeTransform {
|
||||||
*/
|
*/
|
||||||
@Pipe({name: 'currency'})
|
@Pipe({name: 'currency'})
|
||||||
export class CurrencyPipe implements PipeTransform {
|
export class CurrencyPipe implements PipeTransform {
|
||||||
constructor(@Inject(LOCALE_ID) private _locale: string) {}
|
constructor(
|
||||||
|
@Inject(LOCALE_ID) private _locale: string,
|
||||||
|
@Inject(DEFAULT_CURRENCY_CODE) private _defaultCurrencyCode: string = 'USD') {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param value The number to be formatted as currency.
|
* @param value The number to be formatted as currency.
|
||||||
* @param currencyCode The [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) currency code,
|
* @param currencyCode The [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) currency code,
|
||||||
* such as `USD` for the US dollar and `EUR` for the euro.
|
* such as `USD` for the US dollar and `EUR` for the euro. The default currency code can be
|
||||||
|
* configured using the `DEFAULT_CURRENCY_CODE` injection token.
|
||||||
* @param display The format for the currency indicator. One of the following:
|
* @param display The format for the currency indicator. One of the following:
|
||||||
* - `code`: Show the code (such as `USD`).
|
* - `code`: Show the code (such as `USD`).
|
||||||
* - `symbol`(default): Show the symbol (such as `$`).
|
* - `symbol`(default): Show the symbol (such as `$`).
|
||||||
|
@ -205,7 +210,7 @@ export class CurrencyPipe implements PipeTransform {
|
||||||
display = display ? 'symbol' : 'code';
|
display = display ? 'symbol' : 'code';
|
||||||
}
|
}
|
||||||
|
|
||||||
let currency: string = currencyCode || 'USD';
|
let currency: string = currencyCode || this._defaultCurrencyCode;
|
||||||
if (display !== 'code') {
|
if (display !== 'code') {
|
||||||
if (display === 'symbol' || display === 'symbol-narrow') {
|
if (display === 'symbol' || display === 'symbol-narrow') {
|
||||||
currency = getCurrencySymbol(currency, display === 'symbol' ? 'wide' : 'narrow', locale);
|
currency = getCurrencySymbol(currency, display === 'symbol' ? 'wide' : 'narrow', locale);
|
||||||
|
|
|
@ -89,7 +89,7 @@ import {beforeEach, describe, expect, it} from '@angular/core/testing/src/testin
|
||||||
describe('CurrencyPipe', () => {
|
describe('CurrencyPipe', () => {
|
||||||
let pipe: CurrencyPipe;
|
let pipe: CurrencyPipe;
|
||||||
|
|
||||||
beforeEach(() => { pipe = new CurrencyPipe('en-US'); });
|
beforeEach(() => { pipe = new CurrencyPipe('en-US', 'USD'); });
|
||||||
|
|
||||||
describe('transform', () => {
|
describe('transform', () => {
|
||||||
it('should return correct value for numbers', () => {
|
it('should return correct value for numbers', () => {
|
||||||
|
|
|
@ -14,8 +14,8 @@ import {Console} from './console';
|
||||||
import {Injector, StaticProvider} from './di';
|
import {Injector, StaticProvider} from './di';
|
||||||
import {Inject, Optional, SkipSelf} from './di/metadata';
|
import {Inject, Optional, SkipSelf} from './di/metadata';
|
||||||
import {ErrorHandler} from './error_handler';
|
import {ErrorHandler} from './error_handler';
|
||||||
import {DEFAULT_LOCALE_ID} from './i18n/localization';
|
import {DEFAULT_LOCALE_ID, USD_CURRENCY_CODE} from './i18n/localization';
|
||||||
import {LOCALE_ID} from './i18n/tokens';
|
import {DEFAULT_CURRENCY_CODE, LOCALE_ID} from './i18n/tokens';
|
||||||
import {ivyEnabled} from './ivy_switch';
|
import {ivyEnabled} from './ivy_switch';
|
||||||
import {ComponentFactoryResolver} from './linker';
|
import {ComponentFactoryResolver} from './linker';
|
||||||
import {Compiler} from './linker/compiler';
|
import {Compiler} from './linker/compiler';
|
||||||
|
@ -96,6 +96,7 @@ export const APPLICATION_MODULE_PROVIDERS: StaticProvider[] = [
|
||||||
useFactory: _localeFactory,
|
useFactory: _localeFactory,
|
||||||
deps: [[new Inject(LOCALE_ID), new Optional(), new SkipSelf()]]
|
deps: [[new Inject(LOCALE_ID), new Optional(), new SkipSelf()]]
|
||||||
},
|
},
|
||||||
|
{provide: DEFAULT_CURRENCY_CODE, useValue: USD_CURRENCY_CODE},
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -26,7 +26,7 @@ export {DebugElement, DebugEventListener, DebugNode, asNativeElements, getDebugN
|
||||||
export {GetTestability, Testability, TestabilityRegistry, setTestabilityGetter} from './testability/testability';
|
export {GetTestability, Testability, TestabilityRegistry, setTestabilityGetter} from './testability/testability';
|
||||||
export * from './change_detection';
|
export * from './change_detection';
|
||||||
export * from './platform_core_providers';
|
export * from './platform_core_providers';
|
||||||
export {TRANSLATIONS, TRANSLATIONS_FORMAT, LOCALE_ID, MissingTranslationStrategy} from './i18n/tokens';
|
export {TRANSLATIONS, TRANSLATIONS_FORMAT, LOCALE_ID, DEFAULT_CURRENCY_CODE, MissingTranslationStrategy} from './i18n/tokens';
|
||||||
export {ApplicationModule} from './application_module';
|
export {ApplicationModule} from './application_module';
|
||||||
export {AbstractType, Type} from './interface/type';
|
export {AbstractType, Type} from './interface/type';
|
||||||
export {EventEmitter} from './event_emitter';
|
export {EventEmitter} from './event_emitter';
|
||||||
|
|
|
@ -34,3 +34,9 @@ export function getPluralCase(value: any, locale: string): string {
|
||||||
* The locale id that the application is using by default (for translations and ICU expressions).
|
* The locale id that the application is using by default (for translations and ICU expressions).
|
||||||
*/
|
*/
|
||||||
export const DEFAULT_LOCALE_ID = 'en-US';
|
export const DEFAULT_LOCALE_ID = 'en-US';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* USD currency code that the application uses by default for CurrencyPipe when no
|
||||||
|
* DEFAULT_CURRENCY_CODE is provided.
|
||||||
|
*/
|
||||||
|
export const USD_CURRENCY_CODE = 'USD';
|
||||||
|
|
|
@ -32,6 +32,29 @@ import {InjectionToken} from '../di/injection_token';
|
||||||
*/
|
*/
|
||||||
export const LOCALE_ID = new InjectionToken<string>('LocaleId');
|
export const LOCALE_ID = new InjectionToken<string>('LocaleId');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provide this token to set the default currency code your application uses for
|
||||||
|
* CurrencyPipe when there is no currency code passed into it. This is only used by
|
||||||
|
* CurrencyPipe and has no relation to locale currency. Defaults to USD if not configured.
|
||||||
|
*
|
||||||
|
* See the [i18n guide](guide/i18n#setting-up-locale) for more information.
|
||||||
|
*
|
||||||
|
* @usageNotes
|
||||||
|
* ### Example
|
||||||
|
*
|
||||||
|
* ```typescript
|
||||||
|
* import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||||
|
* import { AppModule } from './app/app.module';
|
||||||
|
*
|
||||||
|
* platformBrowserDynamic().bootstrapModule(AppModule, {
|
||||||
|
* providers: [{provide: DEFAULT_CURRENCY_CODE, useValue: 'EUR' }]
|
||||||
|
* });
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @publicApi
|
||||||
|
*/
|
||||||
|
export const DEFAULT_CURRENCY_CODE = new InjectionToken<string>('DefaultCurrencyCode');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use this token at bootstrap to provide the content of your translation file (`xtb`,
|
* Use this token at bootstrap to provide the content of your translation file (`xtb`,
|
||||||
* `xlf` or `xlf2`) when you want to translate your application in another language.
|
* `xlf` or `xlf2`) when you want to translate your application in another language.
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {LOCALE_ID} from '@angular/core';
|
import {DEFAULT_CURRENCY_CODE, LOCALE_ID} from '@angular/core';
|
||||||
import {ivyEnabled} from '@angular/private/testing';
|
import {ivyEnabled} from '@angular/private/testing';
|
||||||
|
|
||||||
import {getLocaleId} from '../src/render3';
|
import {getLocaleId} from '../src/render3';
|
||||||
|
@ -19,6 +19,11 @@ import {describe, expect, inject, it} from '../testing/src/testing_internal';
|
||||||
it('should set the default locale to "en-US"',
|
it('should set the default locale to "en-US"',
|
||||||
inject([LOCALE_ID], (defaultLocale: string) => { expect(defaultLocale).toEqual('en-US'); }));
|
inject([LOCALE_ID], (defaultLocale: string) => { expect(defaultLocale).toEqual('en-US'); }));
|
||||||
|
|
||||||
|
it('should set the default currency code to "USD"',
|
||||||
|
inject([DEFAULT_CURRENCY_CODE], (defaultCurrencyCode: string) => {
|
||||||
|
expect(defaultCurrencyCode).toEqual('USD');
|
||||||
|
}));
|
||||||
|
|
||||||
if (ivyEnabled) {
|
if (ivyEnabled) {
|
||||||
it('should set the ivy locale with the configured LOCALE_ID', () => {
|
it('should set the ivy locale with the configured LOCALE_ID', () => {
|
||||||
TestBed.configureTestingModule({providers: [{provide: LOCALE_ID, useValue: 'fr'}]});
|
TestBed.configureTestingModule({providers: [{provide: LOCALE_ID, useValue: 'fr'}]});
|
||||||
|
|
|
@ -13,7 +13,7 @@ export declare class CommonModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
export declare class CurrencyPipe implements PipeTransform {
|
export declare class CurrencyPipe implements PipeTransform {
|
||||||
constructor(_locale: string);
|
constructor(_locale: string, _defaultCurrencyCode?: string);
|
||||||
transform(value: any, currencyCode?: string, display?: 'code' | 'symbol' | 'symbol-narrow' | string | boolean, digitsInfo?: string, locale?: string): string | null;
|
transform(value: any, currencyCode?: string, display?: 'code' | 'symbol' | 'symbol-narrow' | string | boolean, digitsInfo?: string, locale?: string): string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -257,6 +257,8 @@ export declare const DebugNode: {
|
||||||
new (...args: any[]): DebugNode;
|
new (...args: any[]): DebugNode;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export declare const DEFAULT_CURRENCY_CODE: InjectionToken<string>;
|
||||||
|
|
||||||
/** @deprecated */
|
/** @deprecated */
|
||||||
export declare class DefaultIterableDiffer<V> implements IterableDiffer<V>, IterableChanges<V> {
|
export declare class DefaultIterableDiffer<V> implements IterableDiffer<V>, IterableChanges<V> {
|
||||||
readonly collection: V[] | Iterable<V> | null;
|
readonly collection: V[] | Iterable<V> | null;
|
||||||
|
|
Loading…
Reference in New Issue