500

Angular 1 does not accept onchange() event, it's only accepts ng-change() event.

Angular 2, on the other hand, accepts both (change) and (ngModelChange) events, which both seems to be doing the same thing.

What's the difference?

which one is best for performance?

ngModelChange:

<input type="text" pInputText class="ui-widget ui-text"
    (ngModelChange)="clearFilter()" placeholder="Find"/>

vs change:

<input type="text" pInputText class="ui-widget ui-text" 
    (change)="clearFilter()" placeholder="Find"/>
Ramesh Rajendran
  • 37,412
  • 45
  • 153
  • 234
  • 1
    If you want to compare the two of them, maybe you can also add `(change)` and `(keyup)` –  Jun 30 '17 at 07:17
  • 2
    I don't want to compare those. I just want to know which one is best for performance ? – Ramesh Rajendran Jun 30 '17 at 07:19
  • 7
    Yeah there is no comparison . If you are using ngModel you can use the later otherwise the first one . Its always preferred to avoid ngModel as that's two way data binding , hence bad for performance – Vamshi Jul 13 '17 at 13:17
  • 2
    Edited to put emphasis on "what's the difference" and "which is more performant" to remove subjectivity & voted to reopen. – ruffin Jul 25 '18 at 19:08
  • 32
    In Angular 7, the (ngModelChange)="eventHandler()" will fire BEFORE the value bound to [(ngModel)]="value" is changed while the (change)="eventHandler()" will fire AFTER the value bound to [(ngModel)]="value" is changed. – CAK2 Dec 27 '18 at 00:29
  • 10
    By the way, the (change) event is fired only when the focus leaves the input. If you want an event fired after each key-press, you can use the (input) event. – John Gilmer Nov 01 '19 at 14:28
  • @CAK2 actually it depends on the ordering of the HTML: https://github.com/angular/angular/issues/28107 – Dinei Apr 07 '20 at 19:44

5 Answers5

711

(change) event bound to classical input change event.

https://developer.mozilla.org/en-US/docs/Web/Events/change

You can use (change) event even if you don't have a model at your input as

<input (change)="somethingChanged()">

(ngModelChange) is the @Output of ngModel directive. It fires when the model changes. You cannot use this event without ngModel directive.

https://github.com/angular/angular/blob/master/packages/forms/src/directives/ng_model.ts#L124

As you discover more in the source code, (ngModelChange) emits the new value.

https://github.com/angular/angular/blob/master/packages/forms/src/directives/ng_model.ts#L169

So it means you have ability of such usage:

<input (ngModelChange)="modelChanged($event)">
modelChanged(newObj) {
    // do something with new value
}

Basically, it seems like there is no big difference between two, but ngModel events gains the power when you use [ngValue].

  <select [(ngModel)]="data" (ngModelChange)="dataChanged($event)" name="data">
      <option *ngFor="let currentData of allData" [ngValue]="currentData">
          {{data.name}}
      </option>
  </select>
dataChanged(newObj) {
    // here comes the object as parameter
}

assume you try the same thing without "ngModel things"

<select (change)="changed($event)">
    <option *ngFor="let currentData of allData" [value]="currentData.id">
        {{data.name}}
    </option>
</select>
changed(e){
    // event comes as parameter, you'll have to find selectedData manually
    // by using e.target.data
}
Michael
  • 8,362
  • 6
  • 61
  • 88
omeralper
  • 9,804
  • 2
  • 19
  • 27
  • 1
    What will happen if I am using change event with ngmodel object? – Ramesh Rajendran Jul 13 '17 at 08:42
  • 6
    @RameshRajendran I've improved the answer. You can still use change event with ngModel object, but change event passes event parameter, ngModelChange event passes new value. – omeralper Jul 13 '17 at 10:43
  • 1
    Yeah +1 . But I have a problem with ngmodelchange, when you clear all the values from text box by using ctr + A. then ngModelChange does not trigger . – Ramesh Rajendran Jul 13 '17 at 11:08
  • 6
    `` is not right, `[ngModel]` is required. – e-cloud Jul 13 '17 at 14:27
  • Any scenario faced in which (change) dosen't fire while selecting dropdown value for the first time ? – forgottofly May 11 '18 at 06:45
  • 3
    Something, you cannot do an `(change)`, in this case, you can do a `(onClick)="yourFunction(youParameter)"` – jpmottin Jun 21 '18 at 08:02
  • 1
    Change event fires when you remove the focus from input text after changing the content. On other hand ngModelChange will trigger with each input change. i.e if you start typing 'abc' ngModelChange will get triggered 3 times and once you remove focus from this field your change event gets fired. – Amitesh Sep 06 '18 at 05:50
  • Genreally, I really don't see the point of adding existing browser functionality on top of existing browser functionality. Same way to use it, different name, probably less functionality than the existing browser method. I feel this way about a lot of what angular tries to achieve. The answer seems good, I just don't understand why we need this. – JohnF Jan 08 '19 at 08:34
  • 1
    Based on https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/change_event , it's `e.target.value` instead of `e.target.data` for `(change)` event – Gerald Hughes Nov 12 '19 at 12:44
  • In option tag, Is {{data.name}} o {{currentData.name}}? – Roque Orts Nov 13 '20 at 09:22
  • A small correction (data -> value): `changed(e: Event){ // event comes as parameter, you'll have to find selectedData manually // by using e.target.value` } – Sinisa Rudan Feb 11 '21 at 12:22
149

In Angular 7, the (ngModelChange)="eventHandler()" will fire before the value bound to [(ngModel)]="value" is changed while the (change)="eventHandler()" will fire after the value bound to [(ngModel)]="value" is changed.

Tiago Martins Peres
  • 14,289
  • 18
  • 86
  • 145
CAK2
  • 1,892
  • 1
  • 15
  • 17
  • 1
    I justed tested in Angular 7.1 and the value from the ngModel is updated before the event is called. So that's what I use – Jahrenski Jan 08 '19 at 17:43
  • It worked in angular 6 as well. +1 for saving my time :) – Hemadri Dasari Feb 05 '19 at 03:57
  • 1
    Isn't it the other way around? According to the Angular [Docs](https://angular.io/api/forms/NgModel) `ngModelChange` fires after the view model updates. – rage Apr 15 '19 at 14:15
  • @rage I didn't read the Angular docs regarding this issue. I wrote this answer at the end of 2018 based on what I saw in the Chrome debugger at the time. – CAK2 Apr 15 '19 at 18:21
  • 3
    In the latest documentation of angular this case is described: https://angular.io/guide/forms-overview#data-flow-in-template-driven-forms – pioro90 May 08 '19 at 09:15
  • 8
    In Angular 7.2, indeed the `(ngModelChange)` event is fired **before** the value is changed and `(change)` **after** it has changed. Thanks for the info, super helpful! – Dennis Ameling May 08 '19 at 13:49
  • " Support for using the ngModel input property and ngModelChange event with reactive form directives has been deprecated in Angular v6 and will be removed in Angular v7." https://angular.io/api/forms/FormControlName#use-with-ngmodel – Auguste Nov 01 '19 at 16:10
  • I feel it's safer to not rely on details like the ordering of _ngModel_ and _ngModelChange_ in your template code, and instead use `[ngModel]="value" (ngModelChange)="value = $event; eventHandler()"`. Note that I am not using the two-way binding syntax (banana in a box). – psq May 31 '20 at 02:09
  • 3
    Why would someone want an function to fire before the value bound to the model has changed? – Asma Rahim Ali Jafri Jul 28 '20 at 18:07
  • 1
    In angular 10 both change and ngModel change appear to fire before the value is updated. How do I get either to fire AFTER the value is updated? – Ya. Aug 13 '20 at 13:08
  • @asma-rahim-ali-jafri One reason to evaluate the function before the model update is to allow validation logic to prevent the input from updating by issuing an event.preventDefault() – pierus Jan 24 '21 at 15:21
  • It's Still true in angular 10 – Gopal Kohli Jan 25 '21 at 17:17
  • See also https://github.com/angular/angular/issues/11234 – Derek718 Jun 10 '21 at 17:48
56

As I have found and wrote in another topic - this applies to angular < 7 (not sure how it is in 7+)

Just for the future

we need to observe that [(ngModel)]="hero.name" is just a short-cut that can be de-sugared to: [ngModel]="hero.name" (ngModelChange)="hero.name = $event".

So if we de-sugar code we would end up with:

<select (ngModelChange)="onModelChange()" [ngModel]="hero.name" (ngModelChange)="hero.name = $event">

or

<[ngModel]="hero.name" (ngModelChange)="hero.name = $event" select (ngModelChange)="onModelChange()">

If you inspect the above code you will notice that we end up with 2 ngModelChange events and those need to be executed in some order.

Summing up: If you place ngModelChange before ngModel, you get the $event as the new value, but your model object still holds previous value. If you place it after ngModel, the model will already have the new value.

SOURCE

Balaj Khan
  • 2,490
  • 2
  • 17
  • 30
Disaster
  • 861
  • 8
  • 6
18

1 - (change) is bound to the HTML onchange event. The documentation about HTML onchange says the following :

Execute a JavaScript when a user changes the selected option of a <select> element

Source : https://www.w3schools.com/jsref/event_onchange.asp

2 - As stated before, (ngModelChange) is bound to the model variable binded to your input.

So, my interpretation is :

  • (change) triggers when the user changes the input
  • (ngModelChange) triggers when the model changes, whether it's consecutive to a user action or not
Julien
  • 2,616
  • 1
  • 30
  • 43
12

As per my experience (change) and (ngModelChange) has two different usage.

  1. (ngModelChange) triggers when HTML renders, user changed the value of that element.

  2. (change) triggers when user changes the value and leave the element focus.

Usage:

  1. (ngModelChange): when you have critical things that depends on html any type of changes that you have to handle.
  2. (change): When you have to handle only value changes done by user.

Note: Be careful while using the (ngModelChange) because sometimes it will give you maximum call stack issue and your form will stuck.

Viplav Soni
  • 1,489
  • 13
  • 18
  • This is what I've also realized from testing. And it is very important because if you want to reduce overhead, you could use change, since it is triggered only when the user leaves the focus of the input, and if there was a change. Thanks. – Dan Ortega Nov 25 '21 at 00:11
  • correct, thanks for comment It will help others to understand – Viplav Soni Nov 25 '21 at 05:31