learn about 2 way data binding and displaying data via *ngFor
What we've learned so far
This tutorial on 2 way data binding in Angular 4 is in continuation of our
Angular 4 Tutorial Series
and if you have not read the previous parts of the tutorial , it is recommended that you go through them first.
In the last part of the tutorial , we created a component for our inventions in our InventionsHub app , in this tutorial , we'll add the functionality to add new inventions and we'll look at how to use *ngFor to display multiple inventions in the InventionsComponent.
The angular features we cover in this part are 2 way data binding and *ngFor .
What needs to be done!
Here's a list of steps we need to perform
Create an array to store our inventions
Add a default invention to our array
declare string type variables nameModel , inventorModel , yearModel to help us add new inventions
add a new method createInvention()
After performing the above steps , our inventions.component.ts file should look like the following. Please read the comments to understand what each line of code is doing.
import { Component, OnInit } from '@angular/core';
// add a new class -- done in previous part of tutorial
export class Invention {
name : String ;
inventor : String ;
year : String;
}
@Component({
selector: 'app-inventions',
templateUrl: './inventions.component.html',
styleUrls: ['./inventions.component.css']
})
export class InventionsComponent implements OnInit {
// declare nameModel , inventorModel , yearModel strings to help with adding new inventions
// make inventions an array to show multiple inventions
nameModel : String;
inventorModel : String;
yearModel : String;
inventions : Invention[];
constructor() {
// initialize model values to ''
this.nameModel = '';
this.inventorModel = '';
this.yearModel = '';
// create a default inventions to show when component renders on screen
let defaultInvention : Invention = {
name: 'C Programming' ,
inventor : 'Dennis Ritche' ,
year : '1972'
};
// add the invention to inventions array
this.inventions = [ defaultInvention ];
}
ngOnInit() {
}
// add create Invention function for adding new inventions
createInvention(){
// initialize a new invention using data coming from template [ using 2 way data binding ]
let newInvention : Invention = {
name: this.nameModel ,
inventor : this.inventorModel ,
year : this.yearModel
};
// push the newly created Invention object to inventions array
this.inventions.push( newInvention );
// set the model values to '' again
this.nameModel = this.yearModel = this.inventorModel = '';
}
}
Great we've setup our component to handle multiple inventions using an array , and we also added a function to create new inventions. Now we'll make changes to the template file inventions.component.html. In angular [ ] brackets are used to bind view elements to component , and ( ) parenthesis are used to take action on different events like click , dataChange etc. In order to achieve 2 way data binding we use [ ( ngModel
) ] , here ngModel is an angular directive. Now let's edit our
inventions.component.html file so it looks like the following. Don't forget to read comments to get more useful information.
<!-- bind data using curly braces to the data in app.component.ts -->
<!-- comment our the data related to single invention we don't need it because
we're using array now -->
<!--
<h2> {{ invention.name }} </h2>
<h3> {{ invention.inventor }} </h3>
<h3> {{ invention.year }} </h3>
-->
<!-- use *ngFor to iterate through array of inventions and print information about them -->
<li *ngFor="let i of inventions">
<span> <b> Name: </b> {{ i.name }} || </span>
<span> <b> Inventor: </b> {{ i.inventor }} || </span>
<span> <b> Year: </b> {{ i.year }} </span>
</li>
<!-- add new inventions -->
<hr>
<!-- Let the user enter information and display the same side by side -->
<label> {{ nameModel }} </label>
<div>
<input [(ngModel)]="nameModel" placeholder="enter name">
</div>
<label> {{ inventorModel }} </label>
<div>
<input type="text" [(ngModel)]="inventorModel" placeholder="enter inventor ">
</div>
<label> {{ yearModel }} </label>
<div>
<input [(ngModel)]="yearModel" placeholder="year">
</div>
<br>
<!-- call the createInvention() function from component on click of button -->
<!-- note the use of parenthesis for the click event -->
<button class="btn" (click)="createInvention()"> create invention </button>
Note the following points in the above inventions.component.html code ::
*ngFor is angular syntax to iterate through array , don't forget the *
ngModel is directive for 2 way data binding
(click) is used to add click handler
2 curly braces {{ }} are used to bind values to view or template
At this point , if you try to run your code using ng serve , your app will break with an error in console saying :: "ngModel ... isn't a known property of input." , don't worry there's nothing wrong with your code. The problem
here is that you need to import FormsModule to work with ngModel , do it as mentioned below.
import FormsModule in app.module.ts
Open your app.module.ts file and import FormsModule from @angular/forms and ensure that your app.module.ts looks like the following after changes.
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { InventionsComponent } from './inventions/inventions.component';
@NgModule({
declarations: [
AppComponent,
InventionsComponent
],
imports: [
BrowserModule ,
FormsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Now you're app is ready with all the new feature that we added , just launch your app with ng serve if not already and go to your browser and point it to http://localhost:4200 Just add more entries to your inventions and they should
reflect on your page.
Summary
In this part of the tutorial , we learned the following
iterating through an array using *ngFor
2 way data binding
calling a function on click of a button in angular
Hope you enjoying learning about the angular 4 , in the next part we'll come back with more exciting Angular 4 stuff.