In this article let us explore the two way data binding in Angular and how NgModel implements the two-way binding in Angular Forms. The ngModel
is a built-in directive and is part of the FormsModule. The Two-way binding uses the syntax [()]
Applies to: Angular 2 to the latest edition of i.e. Angular 8. Angular 9, Angular 10, Angular 11
Table of Content
What is Two way data binding
Two way data binding means that changes made to our model in the component are propagated to the view and that any changes made in the view are immediately updated in the underlying component data.
Two way data binding is useful in data entry forms. Whenever a user makes changes to a form field, we would like to update our model. Similarly, when we update the model with new data, we would like to update the view as well
The two way data binding nothing but both property binding & event binding applied together. Property Binding is one way from view to component. The event binding is one way from component to view. If we combine both we will get the Two-way binding.

Two way using property & Event Binding
The following example shows how we can achieve two-way binding using the combination of property binding & event binding
Create a new Angular application
copy the following code to app.component.html
1 2 3 4 5 6 | h2>Example 1</h2> <input type="text" [value]="name" (input)="name=$event.target.value"> <p> You entered {{name}}</p> <button (click)="clearName()">Clear</button> |
Update the app.component.ts
with the following code.
1 2 3 4 5 6 7 | name="" clearName() { this.name=""; } |
We bind the name
property to the input element ([value]="name"
). We also use the event binding (input)="name=$event.target.value"
. It updates the name
property whenever the input changes. The Angular interpolation updates the {{name}}
, so we know the value of name
property.
Two-way binding syntax
The above example uses the event & property binding combination to achieve the two-way binding. But Angular does provide a way to achieve the two-way binding using the syntax [()]
. Note that both square & parentheses are used here. This is now known as Banana in a box syntax. The square indicates the Property binding & parentheses indicates the event binding.
For Example
1 2 3 | <someElement [(someProperty)]="value"></someElement> |
The above syntax sets up both property & event binding. But to make use of it, the property must follow the following naming convention.
If we are binding to a settable property called someProperty
of an element, then the element must have the corresponding change event named somePropertyChange
Best Angular Books
The Top 8 Best Angular Books, which helps you to get started with Angular
But most HTML elements have a value
property. But do not have a valueChange
event, instead, they usually have an input
event. Hence they cannot be used in the above syntax
For Example, the following will not work as there is no valueChange
event supported by the input
element.
Hence we have a ngModel
directive.
What is ngModel
The Angular uses the ngModel
directive to achieve the two-way binding on HTML Form elements. It binds to a form element like input
, select
, selectarea
. etc.
Internally It uses the ngModel
in property, binding to bind to the value
property and ngModelChange
which binds to the input event.
How to use ngModel
The ngModel
directive is not part of the Angular Core library. It is part of the FormsModule
library. You need to import the FormsModule
package into your Angular module.
In the template use the following syntax
1 2 3 | <input type="text" name="value" [(ngModel)]="value"> |
The ngModel
directive placed inside the square & parentheses as shown above. This is assigned to the Template Expression. Template Expression is the property in the component class
ngModel Example
Import FormsModule
Open the app.module.ts
and make the following changes
1 2 3 | import { FormsModule } from '@angular/forms'; |
Template
1 2 3 4 5 6 | <h2>Example 2</h2> <input type="text" name="value" [(ngModel)]="value"> <p> You entered {{value}}</p> <button (click)="clearValue()">Clear</button> |
Component
1 2 3 4 5 6 7 | value=""; clearValue() { this.value=""; } |
The ngModel
data property sets the element’s value property and the ngModelChange
event property listens for changes to the element’s value.
Run the project and see that as you modify the name, the component class model is automatically updated.
Custom Two-way binding
As we mentioned earlier the [()]
to work, we need to have a property
with the change event as<nameofProperty>Change.
We do not have any HTML Elements which follows the above naming conventions, but we can create a custom component
create a new component and name it as counter.component.ts
. Copy the following code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | import { Component, Input, Output, EventEmitter } from '@angular/core'; @Component({ selector: 'counter', template: ` <div> <p> Count: {{ count }} <button (click)="increment()">Increment</button> </p> </div> ` }) export class CounterComponent { @Input() count: number = 0; @Output() countChange: EventEmitter<number> = new EventEmitter<number>(); increment() { this.count++; this.countChange.emit(this.count); } } |
The component has two properties one is input property count decorated with @Input()
. The other in is an event (or output property), which we decorate with @Output()
. We name the input property as count
. Hence the output property becomes countChange
Now we can use this component and create two-way binding to the count
property using the syntax [(count)]
.
1 2 3 4 5 6 | <h2>Example 3</h2> <counter [(count)]="count"></counter> <p> Current Count {{count}}</p> <button (click)="clearCount()">Clear</button> |
Summary
The two-way binding is a simple, but the yet powerful mechanism. We use the Property binding & Event binding to achieve the two-way binding. Angular does have a [(value)]
syntax to which sets up the two-way binding. It automatically sets up property binding to value property of the element. It also sets up the event binding to valueChange
Property. But since we hardly have any HTML element, which follows those naming conventions unless we create our own component. This is where ngModel
directive from FormsModule
steps in and provides two way binding to all the known HTML form elements.
how to retrive data in table when click on submit
Hi @TEKTUTORIALSHUB,
I found something wrong in What is Two way binding section. In third paragraph, it is written like… event binding is one way from component to view and Property Binding is one way from view to component which is WRONG.
I hope u will correct it soon…
By the way, your tutorials are awesome.
Thank you _/\_
Great Content…..I’m new to Angular….
Thank you.
There’s some missing code for the last section “Custom Two-way binding”.
app.component.ts:
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
count: number = 0;
clearCount() {
this.count = 0;
}
}
Also if you generate your counter.component.ts automatically, the @Component.selector will be
app-counter
, make sure to rename it tocounter
to match the html in app.component.html ( )I have started following your tutorial to learn Angular, albeit I am an intermediate. Splendid!. Many things covered for the in depth knowledge. Please let me know if there is tutorial for web Api as well you recommend?
Thanks Himanshu,
You can refer to the official document for WebAPI in ASP.NET Core
If you are looking in NodeJS WebAPI
Thank you for a good tutorial.
I just started learning AngularJS using your tutorial.
I came this far (custom two way bindings) but the code above throws this error to me:
Property ‘count’ does not exist on type ‘AppComponent’.
I added “” to app.component.html.
Could you tell what I’m doing wrong?
Thank you
I cannot say anything without looking at your code
Please check the spelling of the count in AppComponent