How to specify locale thousand separator for number pipe in Angular 4
Asked Answered
W

7

63

How can I specify/override default (locale) thousand separator for number pipe in Angular 4, e.g.?

{{p.total | number}}

?

Wakeless answered 21/6, 2017 at 9:34 Comment(4)
Possible duplicate of How to set locale for numbers in angular 2.0Immortality
I don't think so. I think OP is not looking for a way to change the default separator, but rather give an argument to the pipe to specify an exceptional one. The latter is not possible unfortunately with Angular's DecimalPipe. You could write your own pipe though.Kenwrick
Here is an issue for it. Join and support it. github.com/angular/angular/issues/33505Verdugo
also you can have a look on that solution (works in Angular 13) https://mcmap.net/q/103936/-apply-existing-pipe-in-a-custom-pipe-duplicateKathernkatheryn
K
53

Angular 5+

Since Angular 5, a locale argument has been added to the decimal pipe as you can see in the official documentation: https://angular.io/api/common/DecimalPipe. That means you can choose your locale directly while calling the pipe, for instance:

{{p.total | number:'':'fr-FR'}}

Just be aware that will also change the decimal separator.


Angular 2+

or if your want to change ONLY the thousands separator...

According to Angular's documentation on DecimalPipe : https://v2.angular.io/docs/ts/latest/api/common/index/DecimalPipe-pipe.html, there is no explicit argument that can be added to the pipe call to exceptionally alter the characters used for formatting.

If you don't want to change the locale or associated default values of your entire project, I think your best shot is to write your own pipe dealing with your special case. Don't worry, pipes are extremely easy to write.

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

@Pipe({
  name: 'numberfr'
})
export class FrenchDecimalPipe implements PipeTransform {

  transform(val: number): string {
    // Format the output to display any way you want here.
    // For instance:
    if (val !== undefined && val !== null) {
      return val.toLocaleString(/*arguments you need*/);
    } else {
      return '';
    }
  }
}

Don't forget to add it to a NgModule to use it.

Kenwrick answered 21/6, 2017 at 10:9 Comment(9)
toLocaleString fails for big numbers. e.g. greater than 9007199254740991. As more than that is not safe JS number value.Hatchet
@Shantanu, wow just learnt about this JS limitation, thanks! Looks like you'd have more to worry about than the formatting function though if you're going beyond MAX_SAFE_INTEGER. Any suggestion to improve my answer?Kenwrick
What if I need to get value something like this 1,23,455,667 ?Newhall
@PardeepJain, well you would code the logic corresponding to the format you're looking for in the transform method. But I think the details about such an implementation are out of the scope of this SO thread.Kenwrick
@AdrienBrunelat yes right, But thought you may be implemented same pipe so asked here, anyways thanksNewhall
Here is an issue for it. Join and support it. github.com/angular/angular/issues/33505 Don't workaround with france language.Verdugo
does not work in Angular 13Kathernkatheryn
@Kathernkatheryn yeah I wouldn’t be surprised since I’ve written that at the time when Angular 2 was a thing. If you can find how to do it, please edit my answer.Kenwrick
@AdrienBrunelat please take a look on this one https://mcmap.net/q/103936/-apply-existing-pipe-in-a-custom-pipe-duplicateKathernkatheryn
I
29

For the number: 1234567

Use the following Pipe:

{{ element.total | number: '.2'}}

In order to produce 1,234,567.00

And Use the following Pipe:

{{ element.total | number: '2.'}}

In order to get rid of the extra 0's and to produce 1,234,567

----------------------------------------------------------------------------------------

Note that the '2.' indicates amount of integers after decimal.

When a value of 0 is loaded in a table using this pipe for example, the displayed value would be '00' (because of the '2.')

To solve this use '1.' instead when input value is 0.

Idiomorphic answered 16/5, 2018 at 6:59 Comment(4)
This is answering about the decimal separator, but the question is about the thousands separator.Simonize
When using the "number" pipe, you get the thousands separatorIdiomorphic
But the question is "How can I specify/override default (locale) thousand separator". Does this answer tell the asker how to specify the separator? Or how to override it? I don't see that.Simonize
While using the number pipe, you're given the thousands separator, when not using it, there's no separator. As for specifying or overriding, there's no way because that will allow you to change the way humans separate thousands rather than tens or hundreds, which would be unacceptable when refering to a number and not a string, if it were a string, that would be a difference case.Idiomorphic
S
17

You can use locale like in this example tested with Angular 6.0.2:

card-component.ts

import { registerLocaleData } from '@angular/common';
import es from '@angular/common/locales/es';
import { Component, OnInit } from '@angular/core';

@Component( {
  selector: 'app-card',
  templateUrl: './card.component.html',
  styleUrls: [ './card.component.css' ]
} )
export class CardComponent implements OnInit {

  value = 1234567.987;

  constructor() { }

  ngOnInit() {
    registerLocaleData( es );
  }

}

card-component.html

<!-- result: 1.234.567,987 -->
<span>{{ value | number:'':'es' }}</span>

You can view other possibilities in https://angular.io/api/common/DecimalPipe and https://angular.io/guide/i18n#setting-up-the-locale-of-your-app official docs.

Seedling answered 16/6, 2018 at 10:8 Comment(0)
G
15

Following is the my solution and it will help to someone.

   
import { Pipe, PipeTransform } from '@angular/core';
    
    @Pipe({
      name: 'amountConverter'
    })
    export class AmountConverterPipe implements PipeTransform {
    
      transform(value: number | string, locale?: string): string {
        return new Intl.NumberFormat(locale, {
          minimumFractionDigits: 2
        }).format(Number(value));
      }
    
    }

Number of digits can change by changing the value of minimumFractionDigits. In the html you can use as follows

<span class="strong">{{Price  | amountConverter:locale}}</span>

Number format will change according to value of locale.

Please refer https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat for more detail.

Grubb answered 15/9, 2017 at 4:20 Comment(2)
The least painful method by far!Versus
Thank you! Intl is the way to go! Why have I never heard of that API before? It's amazing!Feoffee
W
2

You can write a custom pipe for doing this.

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

@Pipe({name: 'seprator'})
export class Seprator implements PipeTransform {
  
  constructor() {

  }

  transform(value: string, unit: string): string {

    if(value == undefined)
    {
        return '';
    }
    let n = parseInt(value);

    const rx =  /(\d+)(\d{3})/;
    return String(n).replace(/^\d+/, function (w) {
        var res = w;
        while (rx.test(res)) {
            res = res.replace(rx, '$1٬$2');
        }
        return res;
    });

  }
}
Wreak answered 14/6, 2019 at 21:12 Comment(0)
E
2

I implemented this for my purpose. Ex:- 12345.67 => 12,345.67

First, I generated a PIpe using ng g pipe pipes/thousandSeparator and I edited that file like this

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

@Pipe({
  name: 'thousandSeparator'
})
export class ThousandSeparatorPipe implements PipeTransform {

  transform(nStr: any): any {
    if (nStr === '') { return ''; }
    let x, x1, x2, rgx;
    nStr += '';
    x = nStr.split('.');
    x1 = x[0];
    x2 = x[1];
    rgx = /(\d+)(\d{3})/;
    while (rgx.test(x1)) {
      x1 = x1.replace(rgx, '$1' + ',' + '$2');
    }
    return x1 + (x2 ? `.${x2}` : '');
  }
}

Also i added it into provider in app.module.ts

providers: [ThousandSeparatorPipe]

Then, I can use it like this.

in components

import { Component, OnInit } from '@angular/core';
import { ThousandSeparatorPipe } from 'src/app/pipes/thousand-separator.pipe';

@Component({
  selector: 'app-my',
  templateUrl: './my.component.html',
  styleUrls: ['./my.component.scss']
})
export class MyComponent implements OnInit {

  value = 12345.67;

  constructor(private thousandSeparator: ThousandSeparatorPipe) { }

  ngOnInit() {
    console.log(this.thousandSeparator.transform(this.value));
  }

}

in html

<p>{{value | thousandSeparator}}</p>
Ephesians answered 28/10, 2020 at 12:28 Comment(0)
B
-1

I know this could be late but hope it helps. angular 2 and above

import { DecimalPipe } from '@angular/common';
import { Component, OnInit } from '@angular/core';

@Component( {
  selector: 'app-card',
  templateUrl: './card.component.html',
  styleUrls: [ './card.component.css' ]
} )
export class CardComponent implements OnInit {

 value = 1234567.987;

 constructor(private decimalPipe: DecimalPipe) { }

 ngOnInit() {
   //here is how to get it
   let newValue = this.decPipe.transform(this.value, '.2');
   //you can now use the newValue
   }

 }

If you want this in html, just do:

{{ value | number: '.2'}}
Brecher answered 6/8, 2018 at 9:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.