Welcome back to the Learn Angular 8 in 10 Days article series - Part 3. In the previous article, we discussed the basic concept of Components. Now, in this article, we will discuss the Concept of Data Binding. If you want to read the previous articles of this series, then follow the links.
So, in this article, we will discuss the concept of Data Binding in Angular 8. Data Binding is one of the most important features of the Angular framework. This is because, at any web-based application, data pushing and pulling is always performed a key role in the development. In Angular, this can be done with the help of the Data Binding concept very easily.
What is data binding?
Data binding is one of the finest and most useful features of the Angular framework. Due to this feature, the developer needs to write less code compared to any other client-side library or framework. Data binding in an Angular application is the automatic synchronization of data between the model and view components. In Angular, we can always treat the model as a single source of truth of data in our web application with the data binding. In this way, the UI or the view always represents the data model at all times. With the help of data binding, developers can establish a relationship between the application UI and business logic. If we establish the data binding correctly, and the data provides the proper notifications to the framework, then, when the user makes any data changes in the view, the elements that are bound to the data reflect changes automatically.
The basic concept of data binding
In the case of any web-based application development, we always need to develop a connection bridge between the back end, where data is stored, and the front end or user interface through which user performs their application data manipulation. Now, this entire process always depends on consecutive networking interactions and repetitive communication between the server (i.e. back end) and the client (i.e. front end).
Due to the consecutive and repetitive communication between client and server, most web framework platforms focus on one-way data binding. This involves reading the input from the DOM, serializing the data, sending it to the back end or server, and waiting for the process to finish. After that, the process modifies the DOM to indicate if any errors occurred or reloads the DOM element if the call is successful. While this process provides a traditional web application all the time it needs to perform data processing, this benefit is only applicable to web apps with highly complex data structures. If your application has a simpler data structure format, with relatively flat models, then the extra work can needlessly complicate the process and decrease the performance of your application.
The angular framework addresses this with the data binding concept. Data binding provides a continuous data upgradation process so that when the user makes any changes in the interface it will automatically update the data and vice-versa. In this way, the data model of the application always acts as an atomic unit so that the view of the application can be always updated concerning the data. This process can be done with the help of a complex series of event handlers and event listeners in many frameworks. But that approach can be fragile very quickly. In Angular Framework, this process related to the data becomes one of the primary parts of its architecture. Instead of creating a series of call-backs to handle the changing data, Angular does this automatically without any needed intervention by the programmer. This feature is a great relief for the programmer and reduces much more development time.
So, the first and foremost advantage of data binding is that it updates the data models automatically concerning the view. So, when the data model updates, that will automatically update the related view element in the application. In this way, angular provides us with a correct data encapsulation on the front end and it also reduces the requirement to perform complex and destructive manipulation of the DOM elements.
Why is data binding required?
From day one, the Angular framework provides this special and powerful feature called Data Binding which always brings smoothness and flexibility to any web application. With the help of data binding, developers can gain better control over the process and steps that are related to the data binding process. This process makes the developer's life easier and reduces development time concerning other frameworks. Some of the reasons related to why data binding is required for any web-based application are listed below.
- With the help of data binding, data-based web pages can be developed quickly and efficiently.
- We always get the desired result with a small volume of coding size.
- Due to this process, the execution time increases. As a result, it improves the quality of the application.
- With the help of an event emitter, we can achieve better control over the data binding process.
Different types of data binding
In Angular 8, there are four different types of Data binding processes available. They are
- Interpolation
- Property Binding
- Two-Way Binding
- Event Binding
Interpolation
Interpolation data binding is the most popular and easiest way of data binding in Angular 8. This feature is also available in previous Angular framework versions. The context between the braces is the template expression that Angular first evaluates and then converts into strings. Interpolation uses the braces expression i.e. {{ }} to render the bound value to the component template. It can be a static string, a numeric value, or an object of your data model. In Angular, we use it like this: {{firstName}}. The below example shows how we can use the interpolation in the component to display data in the front end.
<div>
<span>User Name : {{userName}}</span>
</div>
Property-based binding
In Angular 8, another binding mechanism exists, which is called Property Binding. In nature, it is just the same as interpolation. Some people also called this process as one-way binding like the previous AngularJS concept. Property binding is used [] to send the data from the component to the HTML template. The most common way to use property binding is to assign any property of the HTML element tag into the [] with the component property value, i.e.
<input type="text" [value]="data.name" />
To implement the property binding, we will just make the below changes in the previous HTML file from the interpolation sample i.e. interpolation.component.html.
<div>
<input [value]="value1" />
<br /><br />
</div>
Event binding
Event binding is another of the data binding techniques available in Angular. This data binding technique does not work with the value of the UI elements—it works with the event activities of the UI elements like click-event, blur-event, etc. In the previous version of AngularJS, we always used different types of directives like ng-click, and ng-blur to bind any particular event action of an HTML control. But in the current Angular version, we need to use the same property of the HTML element (like click, change, etc.) and use it within parentheses. In Angular 8, for properties, we use square brackets, and in events, we use parentheses.
<div>
<input type="submit" value="Submit" (click)="fnSubmit()">
</div>
Two-way data binding
In Angular Framework, the most used and important data binding techniques are known as Two-Way Data Binding. Two-way binding is mainly used in the input type field or any form element where the user can provide input values from the browser or provide any value or change any control value through the browser. On the other side, the same is automatically updated into the component variables and vice versa. Similarly, in Angular 8 we have a directive called ngModel, and it needs to be used as below.
<input type="text" [(ngModel)]="firstName"/>
We use [] since it is a property binding, and parentheses are used for the event binding concept i.e. the notation of two-way data binding is [()].
ngModel performs both property binding and event binding. The property binding of the ngModel (i.e. [ngModel]) performs the activity to update the input element with a value. Whereas (ngModel) ( (ngModelChange) event) instructs the outside world when any change occurs in the DOM Element.
The below example demonstrates the implementation of two-way binding. In this example, we define a string variable called strName and assign that variable with a Textbox control. So, whenever we change any content in the textbox, the value of the variable will be changed automatically.
<div>
<input [(ngModel)]="strName" type="text"/>
</div>
@Input() decorator
In Angular Framework, every component is used either as a stateless component or a stateful component. Normally, the components are used in a stateless way. But sometimes we need to use some stateful components. The reason behind using a stateful component in a web application is due to the data passing or receiving from the current component to either a parent component or a child component. So, in this way, we need to inform Angular what type of data or which data may come to our current component. To implement this concept, we need to use the @Input() decorator against any variable. The key features of the @Input() decorator are as follows.
- @Input is a decorator to mark an input property. With the help of this property, we can define an input parameter property just like normal HTML tag attributes to pass and bind that value into the component as a property binding.
- @Input decorator always provides one-way data communications from the parent component to the child component. Using this feature, we can provide some of the value against any property of a child component from the parent components.
- The component property should be annotated with the @Input decorator to act as an input property. A component can receive value from another component using component property binding.
It can be annotated as any type of property, such as a number, string, array, or user-defined class. To use an alias for the binding property name, we need to assign an alias name as @Input(alias). Find the use of @Input with the string data type.
@Input() caption : string;
@Input('phoneNo') phoneNo : string;
In the above example, the best value is the alias name. The alias name is needed when we want to pass the value to the input properties. If an alias is not defined, then we need to use the input property name to pass the value. Now, when we use this component, we need to pass the input values as below.
<demo-app [name]="'Debasis Saha'" [phoneNo]="9830098300"></demo-app>
@Output() decorator
In Angular 8, @Output is a decorator to normally be used as an output property. @Output is used to define output properties to achieve custom event binding. @Output will be used with the instance of Event Emitter. The key features of the @Output() decorator are as follows.
- The @Output decorator binds a component's property to send data from one component (child component) to a calling component (parent component).
- This is one-way communication from a child to a parent component.
- @Output binds a property of the EventEmitter class. If we assume the component is a control, then the output property will act as an event of that control.
- The @Output decorator can also provide options to customize the property name using the alias name @Output(alias). In that case, this custom alias name will act as an event-binding property name of the component.
It can be entered in any property such as a number, string, array, or user-defined class. To use an alias for the binding property name, we need to assign an alias name as @Output(alias). Find the use of @Output with the string data type. Just like the Input decorator, the output decorator also needs to first declare as below.
@Output('onSubmit') submitEvent = new EventEmitter<any>();
Now, we need to raise the emitter from a point within the component so that the event can be raised and tracked by the parent component.
this.submitEvent.emit();
If we want to pass any value through this event emitter, then we need to pass that value as a parameter through the emit(). In the parent component, that output property will be defined as below.
<demo-app (onSubmit)="receiveData($event)"></demo-app>
Demo 1. Interpolation
Now, in this demo, we will show how to use or implement Interpolation in Angular 8 applications for different data types.
app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls : ['./custom.css']
})
export class AppComponent {
public value1: number = 10;
public array1: Array<number> = [10, 22, 14];
public dt1: Date = new Date();
public status: boolean = true;
public returnString(): string {
return "String return from function";
}
}
app.component.html
<div>
<span>Current Number is {{value1}}</span>
<br /><br />
<span>Current Number is {{value1 | currency}}</span>
<br /><br />
<span>Current Number is {{dt1}}</span>
<br /><br />
<span>Current Number is {{dt1 | date}}</span>
<br /><br />
<span>Status is {{status}}</span>
<br /><br />
<span>{{status ? "This is correct status" : "This is false status"}}</span>
<br /><br />
<span>{{returnString()}}</span>
</div>
Now, the output of the above code is as below.
Demo 2. Property-based binding
Now, in this demo, we will demonstrate how to use Property-Based binding in Angular 8. For that, we will add one input type text box in the app.component.html file and bind the text box with variable value1 using property binding.
app.component.html
<div>
<span>Current Number is {{value1}}</span>
<br/><br />
Display Value in Input Controls: <input [value]="value1" />
<br /><br />
<span>Current Number is {{value1 | currency}}</span>
<br /><br />
<span>Current Number is {{dt1}}</span>
<br /><br />
<span>Current Number is {{dt1 | date}}</span>
<br /><br />
<span>Status is {{status}}</span>
<br /><br />
<span>{{status ? "This is correct status" : "This is false status"}}</span>
<br /><br />
<span>{{returnString()}}</span>
</div>
Now, check the output in the browsers.
Demo 3. Event-based binding
In this demo, we will demonstrate how to implement event-based binding in Angular 8.
app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls : ['./custom.css']
})
export class AppComponent {
public showAlert(): void {
console.log('You clicked on the button...');
alert("Click Event Fired...");
}
}
app.component.html
<div>
<h2>Demo of Event Binding in Angular 8</h2>
<input type="button" value="Click" class="btn-block" (click)="showAlert()" />
<br /><br />
<input type="button" value="Mouse Enter" class="btn-block" (mouseenter)="showAlert()" />
</div>
Now, check the output in the browser.
Demo 4. Two-way data binding
Now, in this demo, we will demonstrate how to use two-way data binding in angular. For this purpose, create the below-mentioned components.
app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls : ['./custom.css']
})
export class AppComponent {
public val: string = "";
}
app.component.html
<div>
<div>
<span>Enter Your Name </span>
<input [(ngModel)]="val" type="text"/>
</div>
<div>
<span>Your Name :- </span>
<span>{{val}}</span>
</div>
</div>
Now, when we use ngModel or two-way data binding in our components, then we need to include FormsModule of Angular in our own defined app module file as below. Since ngModel will not work without this FormsModule.
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
FormsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Now, check the output in the browser.
Demo 5. Pass input value into component
In this demo, we will demonstrate how to use or implement the input property of a component. For that purpose, we need to develop the first component in which the input property will be defined.
message.component.ts
import { Component, Input } from '@angular/core';
@Component({
selector: 'message-info',
templateUrl: './message.component.html',
styleUrls : ['./custom.css']
})
export class MessageComponent {
@Input() public message: string = '';
@Input('alert-pop') public message1: string = '';
public showAlert(): void {
alert(this.message1);
}
}
message.component.html
<div>
Message : <h2>{{message}}</h2>
<input type="button" value="Show Alert" (click)="showAlert()"/>
</div>
Now, we need to consume this message-info component into another component and need to pass the input value using input properties.
app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls : ['./custom.css']
})
export class AppComponent {
public val: string = "This is alert popup message";
}
app.component.html
<div>
<message-info [message]="'Demostration of Input Property of a Component'" [alert-pop]="val"></message-info>
</div>
Now, check the output in the browser.
Demo 5. Return output value from a component
Now in this demo, we will discuss how to use the output property of any component. For that purpose, we make the following changes in the message-info component to define the output property.
message.component.ts
import { Component, Input, EventEmitter, Output } from '@angular/core';
@Component({
selector: 'message-info',
templateUrl: './message.component.html',
styleUrls : ['./custom.css']
})
export class MessageComponent {
@Input() public message: string = '';
@Input('alert-pop') public message1: string = '';
@Output() onSignup = new EventEmitter<any>();
public data: any = {};
public showAlert(): void {
alert(this.message1);
}
public onSubmit(): void {
this.onSignup.emit(this.data);
}
}
message.component.html
<div>
Message: <h2>{{message}}</h2>
<input type="button" value="Show Alert" (click)="showAlert()"/>
<br/><br/>
Provide Full Name: <input type="text" [(ngModel)]="data.name">
<br/>
Provide Email Id: <input type="email" [(ngModel)]="data.email">
<br>
<input type="button" value="Sign Up" (click)="onSubmit()"/>
</div>
So, in the above part, we defined an output property called onSignup() within the message-info component. Now, we need to consume that event in the parent component as shown below –
app.component.html
<div>
<message-info [message]="'Demostration of Input Property of a Component'" [alert-pop]="val" (onSignup)="onSignup($event)"></message-info>
</div>
app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls : ['./custom.css']
})
export class AppComponent {
public val: string = "This is alert popup message";
public onSignup(data: any): void {
let strMessage: string = "Thanks for Signup " + data.name + ". ";
strMessage += "Email id " + data.email + " has been registered successfully.";
alert(strMessage);
}
}
Now refresh the browser to check the output.
Conclusion
In this article, we discussed different techniques of data binding in Angular. Also, we discussed the input and output properties of the components. Now, in the next article, we will discuss another important part of Angular i.e. Directives. I hope this article will help you. Any feedback or query related to this article is most welcome.