Angular2 Currency Pipe change decimal separator
Asked Answered
A

5

15

Hello angular friends,

I'm working on an angular2 app (multiple actually). And I live in the Netherlands.

Currently I'm formatting my currency with the following:

{{someIntegerWithCentsToBeDivided / 100 | currency:'EUR':true:'1.0-2'}}

This displays something like 500 to be Eurosign 5 and 501 to be Eurosign 5.01.

Now we dutchies really like comma's the other way around so does anyone know how to change the . to a ,?

Bonus points if someone knows how to show 5,- optionally when there is no cents. My thoughts now would be to extend the CurrencyPipe

Agonize answered 26/4, 2016 at 7:52 Comment(3)
What locale is your browser using? Check navigator.language in the JS console.Kerby
oh, probably uk or us, good call. You're saying that on dutch it should probably actually display the commas?Agonize
That would be my guess, but I haven't actually tried. Incidentally, the CurrencyPipe relies on Intl that's still not supported by some browsers like Safari and older IE versions.Kerby
I
27

Your problem has probably been solved some time ago, but just for reference for other Dutch developers (like myself):

Create a custom Pipe:

import {Pipe} from '@angular/core';
 
@Pipe({
    name: 'currencyFormat'
})
export class CurrencyFormat {
    transform(value: number,
        currencySign: string = '€ ',
        decimalLength: number = 2, 
        chunkDelimiter: string = '.', 
        decimalDelimiter:string = ',',
        chunkLength: number = 3): string {

        value /= 100;

        let result = '\\d(?=(\\d{' + chunkLength + '})+' + (decimalLength > 0 ? '\\D' : '$') + ')';
        let num = value.toFixed(Math.max(0, ~~decimalLength));

        return currencySign+(decimalDelimiter ? num.replace('.', decimalDelimiter) : num).replace(new RegExp(result, 'g'), '$&' + chunkDelimiter);
    }
}

Now you can use:

{{someIntegerWithCentsToBeDivided | currencyFormat}}

The Pipe has already all the Dutch defaults included, but you can easily change them or use them as arguments in the template. For example:

{{1234567 | currencyFormat:'$':2:' ':'.':3}}

will give $12 345.67 as output.

Indiscrimination answered 19/12, 2016 at 14:30 Comment(2)
I'll accept this for now since it is a working version. However what I did is having some default values on my Pipe, and during bootstrap I'd read config and pass settings. This way i could do a simple | money instead of all those options all the time.Agonize
One can remove value /= 100 since it is making an opinion abut the input value. In my case it was already formatted with decimal values.Jacquelynnjacquenetta
E
6

you need import that

import { registerLocaleData } from '@angular/common';
import localeIt from '@angular/common/locales/it'
registerLocaleData(localeIt, 'it');

and add that pipe in view

{{ 1000 | currency: 'EUR':'symbol':'.2-2':'it' }}
Effortless answered 18/9, 2020 at 14:6 Comment(1)
Perfect! Thank you!Ricci
V
5

I'm too late but I found a solution.

I'm just create a pipe to replace anything:

import { PipeTransform, Injectable, Pipe }     from '@angular/core';
@Pipe({
  name: 'replace'
})
@Injectable()
export class ReplacePipe implements PipeTransform {
  constructor(){}
  transform(item: any, replace, replacement): any {
    if(item == null) return "";
    item = item.replace(replace, replacement);
    return item;
  }
}

I used that twice to solve your case.

{{ 5.01999 | currency:'BRL':true | replace:'.':',' | replace:',00':',-' }}}
Vogt answered 7/1, 2017 at 23:33 Comment(4)
It's not the best solution but I can see why this works.Agonize
@MathijsSegers, It's a bad solution. I used another way. I created my own currency pipe to achieve the BRL format with comma.Vogt
@MateusFerreira any concrete reason as to why that is a bad solution?Logistic
@Logistic If you have many locations where you need this implementation it's bloating your code quickly :-). Hence in my implementation I made I Only had to do | money and depending on configuration of my apps it would choose separators and zero cents handling.Agonize
D
0

Fast solution for thousands with "." and decimals with ",":

1) Create new Pipe with command ng g p currencySeparatorFormatter and set the definition as follows:

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

@Pipe({
  name: 'currencySeparatorFormatter'
})
export class CurrencySeparatorFormatterPipe implements PipeTransform {
  transform(value: string|null): string|undefined {
    return value?.replace(/,/gi, "x")
                .replace(/\./gi, ",")
                .replace(/x/gi, ".")
                .replace(/\$/gi, "$ ");
  }
}

Notice: .replace(/\$/gi, "$ "); is optional, only sets a space between "$" symbol and number.

2) Use it inside HTML:

<td>{{room.price | currency: 'BRL' | currencySeparatorFormatter}}</td>
Darrelldarrelle answered 21/11, 2022 at 1:48 Comment(0)
U
-2

I find all of these solutions too big with too many lines of code to achieve something so small. The good thing about them is if you're using them a lot through your app. For smaller cases, I personally would use this approach:

<div>{{(checkout.delivery_fee | currency).replace('.',',')}}</div>

So I can display something like: Delivery fee: $5,50

But, if you need to display a value greather than 1.000, you could use:

<div>{{(checkout.delivery_fee | currency).replace(',','x').replace('.',',').replace('x','.')}}</div>
Unsteel answered 24/10, 2020 at 20:3 Comment(3)
Yes your solution is smaller, but keep in mind that this doesn't tick all the boxes and is not flexible. The case I was looking for (those many many years ago) is more complex than your solution, which is hard to read and not re-usable in it's current form.Agonize
@MathijsSegers Yes, as stated, the other solutions are better if you're using it a lot. I wrote that in my answer. So maybe it wouldn't be ideal to your 2016 question, but still, it works, it is better for smaller cases, and deserves to be available for readers, not downvotedUnsteel
I disagree, in this case I'd rather handle the conversion in the component itself and return the value through a public property/getter. replace logic in template just feels like bad practice. I'm sure it'll balance out if my opinion is not shared with readers. People know how to write javascript, in this case we were looking for a solution using internationalisation. Note that many apps support multiple locales, this breaks allowing multiple formats.Agonize

© 2022 - 2024 — McMap. All rights reserved.