Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Currency Pipe: Be able to set/change the default currency. #25461

Open
agusdutra opened this Issue Aug 13, 2018 · 16 comments

Comments

Projects
None yet
@agusdutra
Copy link

agusdutra commented Aug 13, 2018

I'm submitting a...


[ ] Regression (a behavior that used to work and stopped working in a new release)
[ ] Bug report  
[ ] Performance issue
[X ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
[ ] Other... Please describe:

Current behavior

When using CurrencyPipe if you want to show a different currency than US Dollars, you have to set explicitly every time that you use the pipe in the templates.

<span> {{ 1200.18 | currency }} </span>

Output: $ 1,200.18

<span> {{ 1200.18 | currency:'GBP' }} </span>

Output: £1,200.18

Expected behavior

Be able to set in the root module, the default currency that you want to use using provide: CURRENCY_ID
The currency symbol that is going to show by default when no currency is specified in the template, is the one defined in the loaded locale for that currency code.

For Example:

app.module.ts:

providers: {provide: CURRENCY_ID, useValue: 'GBP'}]

component.html:

<span> {{1200.18 | currency }} </span>

If I'm using LOCALE_ID = 'en'

Output: £1,200.18

If I'm using LOCALE_ID = 'es'

Output: 1.200,18 GBP

Minimal reproduction of the problem with instructions

What is the motivation / use case for changing the behavior?

I'm developing an application for a country where the Locale that we use, uses the symbol US$ for dollars.
So every time you use {{ 1200.18 | currency }} it outputs: US$ 1.200,18. And we don't want to use dollars.

We have a lot of currency outputs to display in our local currency (pesos, $) and found that expliciting it in every place we use, was not the best way to go.

We found a way of working this around, but for sure it's not the best option, I think this feature request would be a more suitable option.
What we did was change that 'US$' symbol for dollars:

const currencySymbols = localeUy[LocaleDataIndex.Currencies];
currencySymbols['USD'] = ['$', '$']; // Previous value was : ['US$', '$']
registerLocaleData(localeUy, 'en');

That way, we could without expliciting in the templates the currency, show the code $ for currencies with the locale 'es-UY'

Others:

Issue associated with the request: #22519

@benlesh benlesh added the comp: misc label Aug 13, 2018

@ngbot ngbot bot added this to the needsTriage milestone Aug 13, 2018

@MRMokwa

This comment has been minimized.

Copy link

MRMokwa commented Aug 15, 2018

Yes, this is really necessary. Writing in every single template {{value | currency:'BRL'}} doesn't seem like a great solution.

@vicb vicb added the type: feature label Aug 15, 2018

@ngbot ngbot bot modified the milestones: needsTriage, Backlog Aug 15, 2018

@Wilt

This comment has been minimized.

Copy link

Wilt commented Sep 13, 2018

The problem lies in this line:

var currency = currencyCode || 'USD';

When no currencyCode is passed the fallback is simply a hardcoded string 'USD'. This could be changed so it is configurable just like done for locale.
The line above would become:

var currency = currencyCode || _currencyCode;

And the value can be injected in the constuctor like done for locale:

@Inject(CURRENCY_CODE) private _currencyCode: string

CURRENCY_CODE could by default still be set to 'USD' but can be configured through a provider the same way like @agusdutra suggested in his answer.

  providers: [
      { provide: CURRENCY_CODE, useValue: "EUR" },
  ],

I think this will make a lot of angular users very happy, there are an enormous amount of posts/issues on this topic.

@simeyla

This comment has been minimized.

Copy link

simeyla commented Oct 21, 2018

No! The currency pipe encourages bad behavior in the first place.

We should be using the 'money pattern' and always storing currency alongside the value. This makes it infinitely easier if you decide at some future point to support multiple currencies.

Currency pipe should check to see which of { currency: string, amount: number } | number is used for the value passed in and act accordingly.

I wish they'd do this in the official pipe, but in the meantime I'm implementing this myself as my own pipe.

https://martinfowler.com/eaaCatalog/money.html

@MickL

This comment has been minimized.

Copy link

MickL commented Oct 23, 2018

When i register the language an set the locale:

registerLocaleData(localeEs, 'es');

// ...

providers: [
    {
      provide: LOCALE_ID,
      useValue: 'es',
    }
  ],

I expect the currency-code to change (to Euro). The format is already changing from "$20.00" to "20,00 $", but the currency-code stays dollar.

@chaosmonster

This comment has been minimized.

Copy link

chaosmonster commented Oct 23, 2018

I like the idea of a global CURRENCY_ID as a fallback, but I woudn't make it related to the LOCALE_ID. As @Wilt already pointed out where it can be found why not add a "easy first contribution" label to this?

@MickL

This comment has been minimized.

Copy link

MickL commented Oct 23, 2018

But the format is also related to LOCALE_ID ?

@agusdutra

This comment has been minimized.

Copy link
Author

agusdutra commented Oct 23, 2018

@MickL the locale will change the way dollars is shown according to 'es' definition, but not the currency. Because dollars is set to default in currency.
That is wat this feature request is about, to be able to set the currency in a general way similar to the locale.

@MickL

This comment has been minimized.

Copy link

MickL commented Oct 23, 2018

I would say it is a "bug" that the currency-code does not change but the format does. So this issue would be obsolet.

@chaosmonster

This comment has been minimized.

Copy link

chaosmonster commented Oct 23, 2018

@MickL Let me give you an example on why the approach to only use the LOCALE_ID would cause problems.
Let's say I have a app that provides German (de) and English (en). And I have prices in Euro in this app.
Your approach means that when I change the LOCALE_ID to en that my prices switch from Euro to GBR.
When using a CURRENCY_ID those are separated and can change separate.

@MickL

This comment has been minimized.

Copy link

MickL commented Oct 23, 2018

Yes thats nice and i would appreciate that, but currently as of Angular 7 if you set locale_id, e.g. to "es", it will change format from: $ 20.00 to 20,00 $. So if you want to change the currency independent from the language/locale then the whole locale-stuff needs to be refactored or you should find another way.

@agusdutra

This comment has been minimized.

Copy link
Author

agusdutra commented Oct 23, 2018

The currency is already independent from the locale.
That change from $ 20.00 to 20,00 $ is because for the locale 'en' the symbol goes before the number and the decimal separator is a dot, and for 'es' goes after and the decimal separator is a comma.
The currency is never affected.
We are requesting a way to be able to set the default currency for the project, because today is set to dollars and no matter which locale you set, the currency will be dollars.

@chaosmonster

This comment has been minimized.

Copy link

chaosmonster commented Oct 23, 2018

I can't find a global example so fast, but the Euro for example depends on the locale not the currency https://en.wikipedia.org/wiki/Language_and_the_euro#Summary so the formatting is dependent on the locale the currency I want to use as default is something different and should be made settable e.g with CURRENCY_ID

agusdutra pushed a commit to agusdutra/angular that referenced this issue Oct 23, 2018

feat(common): inject CURRENCY_ID in number_pipe constructor
change constructor to accept an injected CURRENCY_ID(similar to LOCALE_ID) and use it as a default when no currencyCode is provided, before 'USD' fallback.
Now currency code still is by default 'USD', but can be changed in a provider using provide and useValue:
  providers: [
      { provide: CURRENCY_ID, useValue: "EUR" },
  ],

Closes angular#25461, angular#22519
@agusdutra

This comment has been minimized.

Copy link
Author

agusdutra commented Oct 24, 2018

I've created a branch to add the solution as @Wilt suggested. But I'm missing where to update the docs to be able to make the pull request.

gund added a commit to gund/angular that referenced this issue Dec 12, 2018

@DmitryEfimenko

This comment has been minimized.

Copy link

DmitryEfimenko commented Feb 11, 2019

@agusdutra what happened to that PR of yours? This would be a great feature!

@agusdutra

This comment has been minimized.

Copy link
Author

agusdutra commented Feb 11, 2019

@DmitryEfimenko I had some trouble with the CI and left it behind when I saw @gund was doing the same. But I'll open a new one.

@gund

This comment has been minimized.

Copy link

gund commented Feb 11, 2019

@agusdutra I was working on this feature but then I found that some tests were failing even without my changes so I basically gaveup.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.