Angular 2 Template-Driven Forms in One Go

After a long break, let's get back into the flow with a simple tuts.

No server-rendering-worker-asynchronous-resolution-injection here, just something that everybody use: forms!

Today we take a look at how template-driven forms work in Angular 2.

A 5-minutes read to slowly get back in form.

First we need to import FormsModule into our app.module.ts file:

import { NgModule } from '@angular/core' ; import { FormsModule } from '@angular/forms' ; import { HomeComponent } from './home/home.component' ; @ NgModule ( { imports : [ . . . FormsModule , . . . ] , declarations : [ . . . HomeComponent . . . ] bootstrap : [ AppComponent ] } ) export class AppModule { . . . }

Then we create the HTML template:

< form #userForm = " ngForm " (ngSubmit) = " onFormSubmitted(userForm) " > < label > < span > Name </ span > < input type = " text " name = " name " placeholder = " Name " [(ngModel)] = " user.name " required > </ label > < div > < label > < span > Email </ span > < input type = " email " name = " email " placeholder = " Email " [(ngModel)] = " user.email " required > </ label > </ div > < div ngModelGroup = " address " > < label > < span > Country </ span > < input type = " text " name = " country " placeholder = " Country " [(ngModel)] = " user.address.country " required > </ label > < div > < label > < span > City </ span > < input type = " text " name = " city " placeholder = " City " [(ngModel)] = " user.address.city " required > </ label > </ div > </ div > < input type = " submit " [disabled] = " userForm.invalid " > </ form >

First we create a variable that will reference ngForm and contain the form itself.

On submit, we will trigger the function onFormSubmitted and pass this variable.

Then we create some inputs for the user.

([ngModel]) will activate the double binding and store everything into the user object.

The ngModelGroup directive will create an object address inside this user object.

For the finishing the touch, we disable the submit button if the form is invalid.

Before jumping into the Controller, let's create an Interface that will formalize the data structure:

export interface User { name : string ; email : string ; address : { country : string , city : string } ; }

Module: Ready.

Template: Ready.

Interface: Ready.

The only thing left now is the Controller!

import { Component } from "@angular/core" ; import { User } from "../user/user.d" ; @ Component ( { selector : "my-home" , templateUrl : "./home.component.html" } ) export class HomeComponent { user : User = { name : "" , email : "" , address : { country : "" , city : "" } } ; onFormSubmitted ( userForm ) { console . log ( "Model returned for user:" , this . user ) ; console . log ( "Form data returned for user:" , userForm . value ) ; } }

We grab our User Interface and initialize our user.

Finally, the onFormSubmitted function where you do your business logic.

We log the userForm.value and our user variable.

At this point, both have the same content and that's what we expected!

From here the power is yours, use the form or the model.

Quiz time! 3 questions...

What will be the consequences if we change the value of the form in the onFormSubmitted function?

What about changing the value of the user model?

What about using [ngModel] or ngModel instead of ([ngModel])?

I'll let you think about this ;).