62

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

{{p.total | number}}

?

G. Stoynev
  • 7,389
  • 6
  • 38
  • 49
dragonfly
  • 17,407
  • 30
  • 110
  • 219
  • 2
    Possible duplicate of [How to set locale for numbers in angular 2.0](https://stackoverflow.com/questions/37684360/how-to-set-locale-for-numbers-in-angular-2-0) – Pac0 Jun 21 '17 at 09:44
  • 1
    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. – Adrien Brunelat Jun 21 '17 at 10:06
  • Here is an issue for it. Join and support it. https://github.com/angular/angular/issues/33505 – Domske Oct 31 '19 at 10:18
  • also you can have a look on that solution (works in Angular 13) https://stackoverflow.com/a/71145036/961631 – serge Feb 21 '22 at 10:35

7 Answers7

52

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.

Adrien Brunelat
  • 4,492
  • 4
  • 29
  • 42
  • 1
    toLocaleString fails for big numbers. e.g. greater than 9007199254740991. As more than that is not safe JS number value. – Shantanu Jan 22 '18 at 16:59
  • @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? – Adrien Brunelat Jan 22 '18 at 17:06
  • 1
    What if I need to get value something like this `1,23,455,667` ? – Pardeep Jain May 18 '18 at 06:49
  • 2
    @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. – Adrien Brunelat May 18 '18 at 08:46
  • @AdrienBrunelat yes right, But thought you may be implemented same pipe so asked here, anyways thanks – Pardeep Jain May 18 '18 at 09:36
  • Here is an issue for it. Join and support it. https://github.com/angular/angular/issues/33505 Don't workaround with france language. – Domske Oct 31 '19 at 10:18
  • does not work in Angular 13 – serge Feb 16 '22 at 16:16
  • @serge 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. – Adrien Brunelat Feb 17 '22 at 19:13
  • @AdrienBrunelat please take a look on this one https://stackoverflow.com/a/71145036/961631 – serge Feb 21 '22 at 10:34
28

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.

Itamar
  • 885
  • 1
  • 9
  • 17
  • 21
    This is answering about the decimal separator, but the question is about the **thousands** separator. – ANeves Oct 22 '18 at 13:57
  • 3
    When using the "number" pipe, you get the thousands separator – Itamar Oct 23 '18 at 10:25
  • 1
    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. – ANeves Oct 27 '18 at 21:41
  • 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. – Itamar Oct 28 '18 at 11:22
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.

JavierFuentes
  • 1,840
  • 18
  • 13
12

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.

Anjum....
  • 4,086
  • 1
  • 35
  • 45
Janith Widarshana
  • 3,213
  • 9
  • 51
  • 73
1

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;
    });

  }
}
Amir Ajorloo
  • 85
  • 1
  • 5
1

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>
Sanka Sanjeewa
  • 1,993
  • 14
  • 16
-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'}}