user122222
user122222

Reputation: 2429

Using number pipe in input gives Nan angular

I want to make all numbers to be formatted based on our application language, so I made a pipe, where I pass locale and value. (similar to number pipe, just no need to register locale in app.module) and in all edit modals where input is also a number it has to be formatted when user clicks outside the input. However I get error when input is formatted and user edits it again.

I added a working sample here: https://stackblitz.com/edit/decimal-pipe-comma-separator-example-arg-h3gtrw

in the input enter e.g. 11111, then click outside you see input was formatted to 111,11 then add .33 and it just gives NaN.

how can I fix this? I thought of removing thousand separators (and leaving just decimal separator) before returning transformed value in my number.pipe.ts . But how do I get thousand separator? In EN it's , in DE it's . but I didn't find function to get separator based on locale.

//pipe
 */

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

@Pipe({ 
    name: 'numberFormat'
 })
export class NumberFormatPipe implements PipeTransform {
    transform(value: number | string, minFractionDigits: number = 0, maxFractionDigits: number = 2, locale: string = 'en'): string {
        return new Intl.NumberFormat(locale, {
            minimumFractionDigits: minFractionDigits,
            maximumFractionDigits: maxFractionDigits
        }).format(Number(value));
    }
}
<div>
  <input type="text" [ngModel]="userNum | numberFormat"
                                (ngModelChange)="userNum=$event" [ngModelOptions]="{updateOn:'blur'}">
</div>

Upvotes: 0

Views: 3327

Answers (4)

Janos Vinceller
Janos Vinceller

Reputation: 1266

I think the answer you're looking for is described here: https://angular.io/api/common/NumberSymbol

So like this:

getLocaleNumberSymbol('de-DE', NumberSymbol.Decimal);

Please also note that you have to register your locale in your module: https://angular.io/api/common/registerLocaleData

registerLocaleData(localeDe, LOCALE_ID, localeDeExtra);

I made a small demo for the usage: https://stackblitz.com/edit/angular-locale-number-symbol

Upvotes: 0

Venkatesh Parihar
Venkatesh Parihar

Reputation: 79

just initialize it with default value 0 or you can use mask directive (ngx-currency)

Upvotes: 0

StepUp
StepUp

Reputation: 38154

You need to remove unnecessary literals in your pipe code:

value = value.toString().replace(/\D/g, "");

The whole code:

export class NumberFormatPipe implements PipeTransform {
    transform(value: number | string, minFractionDigits: number = 0, 
        maxFractionDigits: number = 2, locale: string = 'en'): string 
    {
        value = value.toString().replace(/\D/g, "");
        console.log(`value:`, value)        
        return new Intl.NumberFormat(locale, {
            minimumFractionDigits: minFractionDigits,
            maximumFractionDigits: maxFractionDigits
        }).format(Number(value));
    }
} 

UPDATE:

If you want to make 11,111,55:

value = value.toString().replace(',', "");

A stackblitz example can be seen here

UPDATE 1:

You can make decision based on locale:

if(locale =='en')
   value = value.toString().replace(/\D/g, "");
else
   value = value.toString().replace(',', "");

Or try to use built-in Angular decimal pipe. It has parameter locale, so your unnecessary code such as if or elsecan be eluded.

Upvotes: 1

Antoniossss
Antoniossss

Reputation: 32537

As you can see in the docs

https://angular.io/api/common/DecimalPipe

DecimalPipe has optional locale argument. Set it to correct value and it should work.

{{ value_expression | number [ : digitsInfo [ : locale ] ] }}

Upvotes: 1

Related Questions