Angular Icon Get 73% off the Angular Master Bundle!

See the bundle then add to cart and your discount is applied.

0 days
00 hours
00 mins
00 secs

Write Angular like a pro. Angular Icon

Follow the ultimate Angular roadmap.

Difference between (change) and (ngModelChange) in Angular

In this post we’re going to cover the difference between (change) and (ngModelChange) events with an <input> inside an Angular component.

First we need to understand that change is not an “Angular event”, it’s a DOM event.

Whereas ngModelChange is an Angular event. It fires when ngModel changes.

Essentially, we want to learn the difference between these and learn which one to use:

<input [value]="foo" (change)="changeFn($event)">
<input [ngModel]="bar" (ngModelChange)="modelChangeFn($event)">

The answer already lives above in our ngModel.

The (change) binding is listening for a DOM event called change, which will give us exactly what we’d expect in “plain JavaScript DOM” outside of the Angular system. Our changeFn($event) would then be given the regular Event object.

But (ngModelChange) is inside the Angular system, and we can further understand the difference between the two events by looking at the ngModel directive. The modelChangeFn($event) I’ve passed in will also give us something different to the previous changeFn($event) too, we’ll come onto this!

Before we do that, here’s how we’d typically use ngModel with its shorthand binding and event syntax (understanding this will make our lives easier):

<input [(ngModel)]="bar">

The above syntax is simply shorthand for an event callback and a model set all at once.

When the user wants to change the model, by entering text into the input, the event callback fires and sets the new value to the model.

So why (ngModelChange)? If we look at the ngModel directive source code we can see an @Output() (because it’s a directive it has an output). Here’s what the source reveals:

export class NgModel {
  //...
  @Output('ngModelChange') update = new EventEmitter();
  //...
}

The NgModel class has the update property with an EventEmitter instance bound to it. This means we can’t use (ngModelChange) without ngModel.

Whereas the (change) event can be used anywhere, and I’ve demonstrated that above with the [value] property binding instead.

It’s also worth noting that (ngModelChange) will only fire when the model is intended to be updated. Again here’s a piece from the ngModel source code:

export class NgModel {
  //...
  viewToModelUpdate(newValue: any): void {
    this.viewModel = newValue;
    this.update.emit(newValue);
  }
  //...
}

Something inside Angular will call viewToModelUpdate as we’re taking the model from our view (the input) and wanting to pass that update to the model, a well named method I’d say.

Really, if you’re using ngModel, you can just use the normal two-way binding syntax [(ngModel)] to sync both view and model at all times.

Comparing $event arguments

Let’s have a look at the differences that (change) and (ngModelChange) both give us. I’ve created this component to demonstrate the differences:

@Component({
  selector: 'my-app',
  template: `
  <div>
    <input [value]="foo" (change)="changeFn($event)">
    <p>{{ foo }}</p>
    <input [ngModel]="bar" (ngModelChange)="modelChangeFn($event)">
    <p>{{ bar }}</p>
  </div>
  `
})
export class AppComponent {
  foo = 'Hello';
  bar = 'World';
  changeFn(e) {
    this.foo = e.target.value;
  }
  modelChangeFn(value) {
    this.bar = value;
  }
}

There are a few things to note here:

And also:

What about when the event fires and the model value is set?

Start typing in the live Stackblitz demo to see the models reflect in different ways:

Angular Directives In-Depth eBook Cover

Free eBook

Directives, simple right? Wrong! On the outside they look simple, but even skilled Angular devs haven’t grasped every concept in this eBook.

  • Green Tick Icon Observables and Async Pipe
  • Green Tick Icon Identity Checking and Performance
  • Green Tick Icon Web Components <ng-template> syntax
  • Green Tick Icon <ng-container> and Observable Composition
  • Green Tick Icon Advanced Rendering Patterns
  • Green Tick Icon Setters and Getters for Styles and Class Bindings

Summary

Really, it comes down to using ngModel or not. If you’re using [(ngModel)] then you don’t need to worry about this, otherwise use (change) if you really want to provide some level of custom event or intercept the event before setting the model.

It’s always great to explore the source code, and I’d encourage you to check out the links above in your own time to learn a little more.

If you are serious about your Angular skills, your next step is to take a look at my Angular courses where you’ll learn Angular, TypeScript, RxJS and state management principles from beginning to expert level.

Now we fully understand the difference between (change) and (ngModelChange)! I hope you enjoyed the post, thanks for reading!

Related blogs 🚀

Free eBooks:

Angular Directives In-Depth eBook Cover

JavaScript Array Methods eBook Cover

NestJS Build a RESTful CRUD API eBook Cover