(ngModelChange) does not update the UI for specific input

Issue

I have an input field where the user can enter the rate of something.

When the user enters a value, I want it to be displayed after rounding it off and then the updated value to be stored on the backing model in ts file.

Using an Angular pipe isn’t good for this since a pipe in one directional and the updated value won’t be reflected on the model.

So to make it bidirectional, I’m doing the following:

<input type="text" [ngModel]="model.rate" (ngModelChange)="model.rate=roundRate($event)" name="rate" />

The roundDate function looks like this

roundRate(value) {
    return Math.round(value);
}

Now when I enter values like 5.6, 7.8, 9.5 etc they’re all rounded off, displayed and stored on the model to 6, 8 and 10 respectively, which is the expected behavior.

The problem starts when I enter 2.1, 3.4, 5.3 etc. In this case, the roundRate function gets called and it returns the value after rounding off. But the values shown on screen are still the old values (2.1, 3.4, 5.3)

I inspected the input element on Chrome and found that the ng-reflect-model property was getting updated to the expected values (2, 3, 5).

<input _ngcontent-c39="" name="rate" type="text" ng-reflect-name="rate" ng-reflect-model="5" class="ng-valid ng-dirty ng-touched">

Can someone please explain what is happening here and despite the ng-reflect-model property getting updated why the screen still shows the old values?

Thanks for your help!

Solution

For a cleaner implementation, just use the (change) @Output property and [(ngModel)]. The implementation of roundRate will change something like this:

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {

  model = { rate: null };

  roundRate() {
    this.model.rate = Math.round(+this.model.rate);
  }
}

And in template:

<input type="text" [(ngModel)]="model.rate" (change)="roundRate()" name="rate" />

PS: This will update the value only once you blur from your input field


Here’s a Sample StackBlitz for your ref.

Answered By – SiddAjmera

Answer Checked By – Mary Flores (AngularFixing Volunteer)

Leave a Reply

Your email address will not be published.