Two Way Data Binding and Pipes in Angular
In all our articles we have been using one way bindings. For property binding and interpolation it is from the component to the template (or view to be precise) and for event binding it’s from the template to the component. We could not communicate in both way at the same time or with the same syntax. That is an annoying problem for us. We found it more annoying when we had to code with that input text box in a previous article. But what to do when we want to flow data in both directions? Angular provides two way binding syntax and a directive for doing that easily. The directive we are talking about is ngModel and the syntax we are talking about is [(directive)]="a_variable". Yes, it is a mix of property binding and event binding syntax.
Before we move forward let’s prepare our initial code. Remove the code we previously had. We want to have an input field, a button, and a div to display our data. Our app.component.html should look like below:
<h1>Two Way Data Binding</h1>
<input type="text" [(ngModel)]="input_data" value=""> <br>
<button type="button">React</button>
<div>
Input data: {{ input_data }}
</div>
So, we want to keep the input data in a component field named input_data, we want to display that data in the div without us doing anything extra as we had to do before. It's Angular's responsibility to make the magic happen. At this moment the button will do nothing. Let's edit our app.component.ts
import { Component } from '@angular/core';
interface ISocialLink{
title: string;
link: string;
is_active: boolean;
}
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
input_data: string = "";
}
Fire up your development server, go to the browser and see what happens. It should show an empty screen. Go to browser's development console and you will see the following error:
Error: Template parse errors:
Can't bind to 'ngModel' since it isn't a known property of 'input'. ("<h1>Two Way Data Binding</h1>
<input type="text" [ERROR ->][(ngModel)]="input_data" value=""> <br>
<button type="button">React</button>
<div>
"): ng:///AppModule/AppComponent.html@1:19
So, Angular did not find the directive called ngModel and it reported that it is not a known property. ngModel is not a DOM property and it's OK for Angular to misunderstand. We did not tell Angular about ngModel and it got broke, it's not Angular's fault, it's ours. ngModel lives in FormsModule. We need to import it and include it in the imports array of our AppModule's NgModule decorator. Our app module can be found in app.module.ts. So, app.module.ts should look like this:
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 { }
Go to the browser again to see it working perfectly. Type, edit, delete text from the text input in the browser and you will see the change reflected in the div below. If you do not understand all those module things now, don't worry, I will write a detailed article on those concepts in future. For now, know that this is how things work. I am following the practical approach, so that you do not get lost in theories, and learn by doing.
Now the change in the variable input_data is being controlled by the two way binding syntax. But we may have requirements to change that variable from other parts of our code. So, what happens when we do that? Let's use our button now, attach a click listener there, tell it to call method named react and see what happens. We will change the variable by appending " : changed!" at the end of it. So, our app.component.ts should look like below:
import { Component } from '@angular/core';
interface ISocialLink{
title: string;
link: string;
is_active: boolean;
}
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
input_data: string = "";
react(){
this.input_data += " : changed!";
}
}
Change the button markup accordingly:
<button type="button" (click)="react()">React</button>
Go to the browser and see the changes happening. Type something inside the input text box, click the react button and you will see the text changed inside the div. Look again, the change is not only in the div, but also in the input text box. So, the data binding is connected in every way.
Now, let's talk about pipes. In simple terms, pipes are what changes data into a new form. Pipes are used inside Angular templates. For example, imagine that you want to change the case of the text inputted through the input box to uppercase inside the div, so that you do not need to do anything extra, write any extra code inside the component and only the text inside the div get transformed. We do not even want to introduce another variable inside the component to keep the transformed result as we do not need that. In this case pipes really come in handy. In this article we will just see howto use pipes. In some future articles I will explain further and teach you the use of parameters, of pipe chaining, and also I will teach you how to create custom pipes. Let's get back to what we want to do here.
The syntax of pipes is simple. You need to provide the variable or value you want to transform followed by a pipe symbol (available with the backward symbol key on your keyboard). Let's learn by doing.
<h1>Two Way Data Binding</h1>
<input type="text" [(ngModel)]="input_data" value=""> <br>
<button type="button" (click)="react()">React</button>
<div>
Input data: {{ input_data | uppercase }}
</div>
Do we need to change code in our component? Do we need to import some module as we had to do for ngModel? No, none of this is needed. Go to the browser, type your data, and see changes happening. Also, try by clicking the react button.
Conclusion
This was the tenth article of this series on learning Angular. I hope that by this time you have gone this far that I can start discussions on intermediate topics and also start to explain the theories—obviously with enough examples and by doing things—of what is what in Angular and how things work. Before going in that direction, I may write more articles where you can learn by working on various other concepts of Angular.
About the Author
My name is Md. Sabuj Sarker. I am a Software Engineer, Trainer and Writer. I have over 10 years of experience in software development, web design and development, training, writing and some other cool stuff including few years of experience in mobile application development. I am also an open source contributor. Visit my github repository with username SabujXi.
Recent Stories
Top DiscoverSDK Experts
Compare Products
Select up to three two products to compare by clicking on the compare icon () of each product.
{{compareToolModel.Error}}
{{CommentsModel.TotalCount}} Comments
Your Comment