Derrek Whistle
Derrek Whistle

Reputation: 711

Regex failing inside Angular 2+ Pipe with Reactive Form

I have the following setup:

The Template:

<form [formGroup]="myForm">
  <input formControlName="amount" placeholder="Amount">
</form>

The Component:

import { Component, OnInit, HostListener } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { UdpCurrencyMaskPipe } from '../../../_helpers/udp-currency- 
mask.pipe';

export class MyComponent implements OnInit {
  myForm: FormGroup;

  constructor(
    private builder: FormBuilder,
    private currencyMask: UdpCurrencyMaskPipe,
  ) {
    this.myForm = builder.group({
      amount: ['', Validators.required]
    });

    this.myForm.valueChanges.subscribe(val => {
      if (typeof val.amount === 'string') {
        const maskedVal = this.currencyMask.transform(val.amount);
        if (val.amount !== maskedVal) {
          this.myForm.patchValue({amount: maskedVal});
        }
      }
    });
  }    
}

The Pipe:

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

@Pipe({
    name: 'udpCurrencyMask'
})
export class UdpCurrencyMaskPipe implements PipeTransform {
    amount: any;

    transform(value: any, args?: any): any {

        let amount = String(value);

        const beforePoint = amount.split('.')[0];
        let integers = '';
        if (typeof beforePoint !== 'undefined') {
            integers = beforePoint.replace(/\d{1,3}(?=(\d{3})+(?!\d))/g, 
'$&,');
        }
        const afterPoint = amount.split('.')[1];
        let decimals = '';
        if (typeof afterPoint !== 'undefined') {
        decimals = afterPoint.replace(/\D+/g, '');
        }
        if (decimals.length > 2) {
            decimals = decimals.slice(0, 2);
        }
        amount = integers;
        if (typeof afterPoint === 'string') {
            amount += '.';
        }
        if (decimals.length > 0) {
            amount += decimals;
        }

        return amount;
    }
}

and the output for this input field is behaving as follows: enter: 1234 output: 1,234 (works as expected) however, if you add an additional number (5 for example), the output will become 1,2,345

I thought that the regex

/\d{1,3}(?=(\d{3})+(?!\d))/g, '$&,'

would place the comma in the proper place (i.e, 12,345 and so on 123,456... etc)

What am I missing? Any help is appreciated, thanks.

Upvotes: 1

Views: 147

Answers (1)

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 627336

It seems you pass the modified string (a string already containing a comma) to the transform function.

You may remove all , chars before manipulations:

let amount = String(value).replace(/,/g, ''); 

Upvotes: 2

Related Questions