'ngModel changes, ngModelChange is not called

<input type="number" style="width: 100px" [(ngModel)]="trait.userMinimum" (ngModelChange)="setThresholds()">

The model gets changed by the below code and is reflected on the screen but then ngModelChange is not called. I want it to be called regardless of it being changed elsewhere or being a property or whatever reason. If the model changes it calls ngModelChange.

  <p-slider [(ngModel)]="trait.userMinimum" 
    [style]="{'width':'100%'}" 
    [min]="trait.min"
    [max]="trait.max"
    class="ui-g-8"></p-slider>
  <span class="ui-g-2">{{trait.max}}</span>

To clarify ngModel works as expected, I move the slider the number changes, I type in the number the slider changes. The only thing that doesn't work is the slider changes and the model change is not called in the input.



Solution 1:[1]

//This is a **two way** binding, so below code will not take effect
[(ngModel)]="trait.userMinimum"  
(ngModelChange)="setThresholds()" //This will not be fired

The solution is to change as below, and remove the "()" so that the get and set are separate:

[(ngModel)]="trait.userMinimum" ---> [ngModel]="trait.userMinimum"

Solution 2:[2]

[(ngModel)] is used for the two way binding like from and to View and component,To use the ngModuleChange we need to split it [()] (Banana into the box) than its become the Property Binding [] and the Event Binding ()

Inside the component.html

<input type="number" placeholder="Enter number" 
   style="width: 100px"
  [ngModel]="trait.userMinimum" 
 (ngModelChange)="setThresholds($event)"/>

And inside the component.ts file , we need to use these setThresholds method which get the value from Editext like below

 setThresholds(getValue)
 {
   console.log(getValue)     
         /**
         * DO YOUR LOGIC HERE
         */
 }

There is also another way to use by the getter and setter property to get and set the data from the view

Solution 3:[3]

This needs to be more like a comment, but putting it as an answer to make it more visible. I got the same error, but unfortunately the above answer did not work. There was also an error in the console which I ignored earlier ERROR Error: If ngModel is used within a form tag, either the name attribute must be set or the form control must be defined as 'standalone' in ngModelOptions. Fixing this issue caused the problem to be fixed.

In a nutshell what I did was adding an additional attribute called name to the input.

<input type="number" name="userMinimum" [(ngModel)]="trait.userMinimum" class="form-control"  (ngModelChange)="setThresholds($event)">

Solution 4:[4]

If you do not want to split [(ngModel)], you can use standard (input) event.

Although you cannot get the full input value, it is great for additional actions.

Solution 5:[5]

Get valuechanges on that field:

@ViewChild('nameOfField') nameOfField: any; 

this.nameOfField.valueChanges.subscribe((v: any) => {
    this.onChange(v);
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 David
Solution 2
Solution 3 Gihanmu
Solution 4 Eugene P.
Solution 5