Angular two-way data binding allows the exchange of data from the component to the view and from the view to the component. It will help users to establish bi-directional communication.
Syntax of Angular two way data binding : ngmodel directive
Angular two-way data binding can be achieved using a ngModel directive in Angular. The ngModel directive is basically the combination of both the square brackets of property binding and parentheses of the event binding.
[(Data Binding Target)] = "Property"
“Data Binding Target” is something in the DOM (including Component and Directive tags) that can be bound to the property of the expression to the right side of the target. For the input box, the data binding target is ngModel, which corresponds to the text in the input box.
The square and parentheses [()] are known as a banana in a box. The [( and )] format is used for two-way binding a property, we can assign data in both view and model and change in one of them will reflect on the other.
When data in the model changes, the view reflects the change, and when data in the view changes, the model is updated as well. This happens immediately and automatically, which makes sure that the model and the view are updated at all times.
The ngModel directive to implment angular two way data binding
The ngModel is a special directive that allows two-way data binding in Angular. Angular is built to generally have data flow in one-way, which we have learned in Angular data binding. However, when it comes to template forms, there are times we use ngModel for two-way data binding for a simple form.
The ngModel directive creates a FormControl instance from a domain model and binds it to a form control element.
Angular two way data binding example
We will create a simple project to implement two-way data binding, where we have a user data object containing name and age. When we change the value in the input of the user in the template and its value will update in the model or component vice versa.
The below image is an Angular two-way binding example.
Step for using ngModel directive in template form
Let us demonstrate how to use the ngModel directive in template form, we have two form fields username and age in the above example.
Step 1: Create a new project to demonstrate ngModel or two-way data binding
ng new twoWayApp
cd twoWayApp
Step 2: Import formsModule in the app.module.ts file
To use the ngModel directive in template form, we have to import an Angular the FormsModule. The ngModel directive is part of the Forms module.
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent,
],
imports: [
BrowserModule,
AppRoutingModule,
FormsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Step 3: Define model or property in component typescript file and edit the app.component.ts
To demonstrate two-way data binding, we added a user object containing the name and age. Initially, we had set both name and age to an empty string.
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: 'app.component.html' ,
styleUrls: ['./app.component.scss']
})
export class AppComponent {
user: any = { name: '', age: '' };
constructor() {}
onLogin() {
console.log('Name :', this.user.name );
console.log('Age', this.user.age );
}
setLoginData() {
this.user.name = 'edupala.com';
this.user.age = '4';
}
}
Step 4: Add ngModel directive on template form input
We had two inputs in template form and for each of them, we had to add the ngModel directive so that we can change both inputs from view or model.
<form>
<div class="form-group">
<label for="exampleInputEmail1">User name</label>
<input class="form-control" [(ngModel)]="user.name" name="name">
</div>
<div class="form-group">
<label for="exampleInputPassword1">User Age</label>
<input class="form-control" [(ngModel)]="user.age" name="age" type="number">
</div>
<button (click)="setUserData()" class="btn btn-primary">
Set data from Model to View
</button>
</form>
<div>
Name: {{ user.name }} Age: {{ user.age }}
</div>
While working with ngModel directive we need to know the following information.
- The ngModel is always used for two-way data binding.
- The ngModel on input should have a name attribute, otherwise, it will not work.
- We don’t use the input value attribute, as it will overwrite by ngModel directive value.
NgModel form control validation or Angular two-way data binding validation
Let’s demonstrate Angular ngmodel validation, using native HTML built-in in form validation elements like required, email, minLength, maxLength, etc.
We have added another field called email to our previous example to demonstrate ngmodel validation. We had added form control validation like required, minLength, and validate email filed.
Let’s add an email field on our user data object in the component typescript file.
user: any = { name: '', email: null, age: '' };
In our component template file, let’s add ngModel directive and validation element on an input field.
<section>
<form>
<div class="form-group">
<label for="exampleInputEmail1">User name</label>
<input class="form-control" [(ngModel)]="user.name" name="name" required
minlength="4" #nameCtrl="ngModel">
</div>
<div *ngIf="nameCtrl.touched" class="invalid-feedback">
<p *ngIf="nameCtrl.errors?.required">
Name is a required field!
</p>
<p *ngIf="nameCtrl.errors?.minlength">
Please enter name with minimum 4 character
</p>
</div>
<div class="form-group">
<label for="exampleInputEmail1">User email</label>
<input class="form-control" type="email" [(ngModel)]="user.email"
name="email" pattern="[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$" required
#emailCtrl="ngModel">
</div>
<div *ngIf="emailCtrl.touched" class="invalid-feedback">
<p *ngIf="emailCtrl.errors?.required">Email is a required field!</p>
<p *ngIf="emailCtrl.errors?.pattern">This is not a valid Email!!!</p>
</div>
<div class="form-group">
<label for="exampleInputPassword1">User Age</label>
<input class="form-control" [(ngModel)]="user.age" name="age" type="number"
#ageCtrl="ngModel" required>
</div>
<div class="invalid-feedback" *ngIf="ageCtrl.errors?.required &&
ageCtrl.touched">
Age is required
</div>
<button (click)="setUserData()" class="btn btn-primary">
Set data from Model to View
</button>
</form>
<div>
<span>Name: {{ user.name }}</span>
<span>Email: {{ user.email }}</span>
<span>Age: {{ user.age }}</span>
</div>
</section>
In our template form, we added the following validation type.
- We had added the required and minLength 4 validation attribute on the input name.
- We have added requirements and patterns to validate email.
- Add required validation on age input.
Now, the question comes, how we can access form control state. To get individual form control state, we had added reference on each input field with # with reference name. Using this reference we can check the control state of each individual input field in template form.
Conclusion
We learned that two-way data binding can achieve only through the ngModel directive and this directive is part of FormsModule. We also learned two-way data binding validation on template form. I hope you got some idea on the ngModel directive.
Related posts
- How to implement Angular ngClass with and without conditions.?
- Angular dynamically adds and removes CSS Classes using ngClass | custom directive.
- An angular directive in detail with an example
- Sharing data between Angular Component
- How to use to implement HighCharts Angular?