Angular 8 Tutorial

How to data binding in Angular 8

learn about 2 way data binding and displaying data via *ngFor




A little background

This tutorial on 2 way data binding in Angular 8 is in continuation of our Angular 8 Tutorial Series and if you have not read the previous parts of the tutorial , it is recommended that you go through them first.

Our inventions hub app

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

  1. Create an array to store our inventions
  2. Add a default invention to our array
  3. declare string type variables nameModel , inventorModel , yearModel to help us add new inventions
  4. 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:
  1. *ngFor is angular syntax to iterate through array , don't forget the *
  2. ngModel is directive for 2 way data binding
  3. (click) is used to add click handler
  4. 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

  1. iterating through an array using *ngFor
  2. 2 way data binding
  3. calling a function on click of a button in angular
Hope you enjoying learning about the Angular 8 , in the next part we'll come back with more exciting Angular 8 stuff.