NgModel Angular and ngModelChange - One and Two Way Data Binding
NgModel Angular and ngModelChange - One and Two Way Data Binding

In this post you will learn how to implement two-way data binding and why do we need ngModel inside Angular.

So the first question is what is the difference between one-way data binding and two-way data binding?

One-way data binding

<input type="text" [value]="searchValue"  />
export class AppComponent {
  searchValue = 'Initial value';
}

Here we created a one-way data binding. We have a value inside our component and our input get a value in the DOM when we change the value in component.

But it works only in one direction this is why it's one-way data binding.

Two-way data binding

Let's make it two way.

<input type="text" [value]="searchValue" (keyup)="searchValueChange($event)" />
{{searchValue}}
export class AppComponent {
  searchValue = 'Initial value';

  searchValueChange(event: Event) {
    const value = (event.target as HTMLInputElement).value;
    this.searchValue = value;
  }

}

Here we added keyup event which allows us to change the variable in the component when our DOM element is changed. We also added a corresponding searchValueChange function for this.

Single input

As you can see in browser changing the input leads to changing the variable which is rerendered in markup. This is how we can implement two-way data binding on our own.

In most cases and projects you will see exactly this code. This is super low level but you can configure and change it how you want.

ngModel

Additionally to that we have ngModel inside Angular.

<input type="text" [(ngModel)]="searchValue" />

Here we created an input without keyup handler but we wrote [(ngModel)] construction. It creates two way data binding automatically. So now when we change the input in the DOM our searchValue changes and the change of searchValue leads to input update.

Under the hood

But actually this ngModel notation is just a sugar in Angular. This is how it looks like without it.

<input
  type="text"
  [ngModel]="searchValue"
  (ngModelChange)="modelValueChange($event)"
/>
export class AppComponent {
  ...
  modelValueChange(value: string) {
    this.searchValue = value;
  }
}

Here we provided separately ngModel and ngModelChange. For ngModelChange we must define a function which gets directly a value of the input. This is exactly the code in Angular under the hood.

3 input

As you can see in browser it works exactly like previous variant.

Template forms

As I already said we don't use ngModel a lot. Where it really shines and why it was created it to make template driven forms inside Angular. If you don't know inside Angular you can write template forms and reactive forms. The better approach would be to write Reactive Forms in RxJS way.

But in order to make starting with forms easier we have template forms. You can use them but they are quite limited because you are writing the whole template and form inside your template. You don't create and configure it inside your component.

<form (ngSubmit)="onSearchFormSubmit()" #searchTplForm="ngForm">
  <input type="text" [(ngModel)]="searchForm.searchValue" name="searchValue" />
  <button type="submit" [disabled]="!searchTplForm.valid">Submit</button>
</form>
export class AppComponent {
  searchForm = {
    searchValue: 'Initial value',
  };

  onSearchFormSubmit(): void {
    console.log('onSearchFormSubmit', this.searchForm);
  }
}

Here we defined a template form with ngModel inside. To define a form we used #searchTplForm="ngForm" construction. As you can see in order to work with form we just update some values inside our component. In our case we created searchForm object for all values of our form which we change with ngModel and two-way data binding.

This is how we use ngModel inside a form. It is not super flexible and I highly recommend you to use Reactive Forms.

And actually if you want to learn Angular with NgRx from empty folder to a fully functional production application make sure to check my Angular and NgRx - Building Real Project From Scratch course.

📚 Source code of what we've done