Search code examples
angularangular-ngmodel

ngModel update is not reflected when I manipulate the updated value in ngModelChange


Here are my TS and HTML files of a component:

<input type="text" [ngModel]="value" (ngModelChange)="setValue($event)">
value: string;

setValue(value: string) {
   const pattern = /[^0-9]/g;
   this.value = value.replace(pattern, '');
   console.log(this.value);  // <- When value is 123a, it puts 123 correctly
}

Stackblitz is added here:

https://stackblitz.com/edit/angular-ng-model-number


It's to replace any non-numeric letters in the value. But the input element is not updated.

So if I input abcd, the input element should be empty but it's not changed.

But as soon as I input a number, for example, abcd1, then the input element shows 1 correctly.

However, the console.log above shows that the this.value is updated correctly.

Any idea why it's happening?


I've tried to use input instead of ngModelChange but it's the same.

<input type="text" [ngModel]="value" (input)="setValue($event.target.value)">

Solution

  • [New]

    I found the proper way to do it (repo).

    First, the html needs to two-way data-bind the ngModel property. Then listen to the input event and change there the value of the ngModel.

    Before inserting the new value to the input, first detect the changes in it and after that, set the new value.

    <input type="text" #input [(ngModel)]="value" (input)="setValue(input.value)" />
    
    constructor(private changeDetector: ChangeDetectorRef) {}
    
    public setValue(value: string) {
      const parsedValue = value || "";
      this.changeDetector.detectChanges();
      this.value = parsedValue.replace(this.pattern, "");
    }
      
    

    [Old response, with ReachtiveForms]

    I'd say that updating the value in those events breaks the change detection.

    I have reproduce your case using the reactive forms method and it works nicely.

    https://stackblitz.com/edit/angular-ng-model-number-ppqajh?file=src/app/app.module.ts