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.
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.
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.
Want to conquer your next JavaScript interview? Download my FREE PDF - Pass Your JS Interview with Confidence and start preparing for success today!
📚 Source code of what we've done