Search code examples
angularangular-pipe

Casting Decimal with fr Locale


I've extended the DecimalPipe and using it for the fr locale.

import { DecimalPipe, registerLocaleData } from '@angular/common';
import { Pipe, PipeTransform } from '@angular/core';
import localeFr from '@angular/common/locales/fr';

@Pipe({
    name: 'myDecimalPipe'
})
export class MyDecimalPipe extends DecimalPipe implements PipeTransform
{
    transform(value: any, args?: any) : any {
        let result;

        registerLocaleData(localeFr);

        result = super.transform(value, args, 'fr');

        return result;
    }
}

Intially when the model binds it is visually displaying the decimal value accordingly to the format.

for e.g. 23.00 is displayed as 23,00but on editing and when it assigns back it is throwing the error

core.js:6185 ERROR Error: InvalidPipeArgument: '23,23 is not a number' for pipe 'DecimalPipe'

Usage:

constructor(private decimalPipe: MyDecimalPipe){}

update()
{
    this.decimalPipe.transform(model.value) //model.value is 23,23
}

What could be the issue here?


Solution

  • for e.g. 23.00 is displayed as 23,00. but on editing and when it assigns back it is throwing the error

    In other words, when you use the DecimalPipe by string interpolation: {{23.03 | myDecimalPipe}} it works and prints 23,03, why? because 23.03 value is a valid number that passes this angular method:

    function strToNumber(value) {
        // Convert strings to numbers
        if (typeof value === 'string' && !isNaN(Number(value) - parseFloat(value))) {
            return Number(value);
        }
        if (typeof value !== 'number') {
            throw new Error(value + " is not a number");
        }
        return value;
    }
    

    When you programmatically calls the transform method you will have to use a valid number.

    console.log(this.decimalPipe.transform("32.23")); // Will print 32,23
    console.log(this.decimalPipe.transform("32,23")); // Throws error
    

    To solve the issue you can simply convert the string "32,23" to a valid number using:

    update()
    {
        this.decimalPipe.transform(Number(model.value.replace(',', '.'));
    }