In this tutorial, we will learn how to set value in template-driven forms in Angular. We will learn how to set the default or initial value to form controls, dynamically set values, reset the value of the form, etc. Learn how to set the value of individual FormControl
or a FormGroup
and nested FormGroup
.
We have covered how to create template-driven forms in the angular tutorial. We will continue from there and in this tutorial, we will show you
Table of Contents
Template
The following is the app.component.html
from the angular template-driven forms tutorial.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | <form #contactForm="ngForm" (ngSubmit)="onSubmit(contactForm)"> <p> <label for="firstname">First Name </label> <input type="text" id="firstname" name="firstname" ngModel> </p> <p> <label for="lastname">Last Name </label> <input type="text" id="lastname" name="lastname" ngModel> </p> <p> <label for="email">Email </label> <input type="text" id="email" name="email" ngModel> </p> <p> <label for="gender">Geneder </label> <input type="radio" value="male" id="gender" name="gender" ngModel> Male <input type="radio" value="female" id="gender" name="gender" ngModel> Female </p> <p> <label for="isMarried">Married </label> <input type="checkbox" id="isMarried" name="isMarried" ngModel> </p> <p> <label for="country">country </label> <select id="country" name="country" ngModel> <option [ngValue]="c.id" *ngFor="let c of countryList"> {{c.name}} </option> </select> </p> <div ngModelGroup="address"> <p> <label for="city">City</label> <input type="text" id="city" name="city" ngModel> </p> <p> <label for="street">Street</label> <input type="text" id="street" name="street" ngModel> </p> <p> <label for="pincode">Pin Code</label> <input type="text" id="pincode" name="pincode" ngModel> </p> </div> <p> <button type="submit">Submit</button> </p> </form> |
Before we set the default value, it is better to create a model class for the above form. Open the app.component.ts
and add the following class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | export class contact { firstname:string; lastname:string; email:string; gender:string; isMarried:boolean; country:string; address: { city:string; street:string; pincode:string; } } |
Set value in template-driven forms
There are two ways you can set the value of the form elements
- Two-way data binding
- Use the template reference variable
Two-way data binding
The two-way data binding.is the recommended way to set the value in the template-driven forms.
The following code uses the [(ngModel)]="contact.firstname"
to bind the firstname
HTML element to the contact.firstname
field in the component class. The advantageous here is that any changes made in the form are automatically propagated to the component class and changes made in component class are immediately shown in the form.
1 2 3 4 | <label for="firstname">First Name </label> <input type="text" id="firstname" name="firstname" [(ngModel)]="contact.firstname"> |
Set the default/initial value
To set the initial or default value all you need to populate the contact model in the ngOnInit
method as shown below
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | ngOnInit() { this.contact = { firstname: "Sachin", lastname: "Tendulkar", gender: "male", isMarried: true, country: "2", address: { city: "Mumbai", street: "Perry Cross Rd", pincode: "400050" } }; } |
Set the value individually or dynamically
1 2 3 4 5 | changeCountry() { this.contact.country = "1"; } |
Reset form
1 2 3 | <button type="button" (click)="reset(contactForm)">Reset</button> |
1 2 3 4 5 | reset(contactForm :NgForm) { contactForm.resetForm(); } |
[tabby title=”app.component.ts”]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | import { Component, ViewChild, ElementRef, OnInit } from '@angular/core'; import { NgForm } from '@angular/forms'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent implements OnInit { title = 'Template driven forms'; countryList: country[] = [ new country("1", "India"), new country('2', 'USA'), new country('3', 'England') ]; contact: contact; ngOnInit() { this.contact = { firstname: "Sachin", lastname: "Tendulkar", gender: "male", isMarried: true, country: "2", address: { city: "Mumbai", street: "Perry Cross Rd", pincode: "400050" } }; } onSubmit() { console.log(this.contact); } setDefaults() { this.contact = { firstname: "Sachin", lastname: "Tendulkar", gender: "male", isMarried: true, country: "2", address: { city: "Mumbai", street: "Perry Cross Rd", pincode: "400050" } }; } changeCountry() { this.contact.country = "1"; } reset(contactForm :NgForm) { contactForm.resetForm(); } } export class contact { firstname: string; lastname: string; email: string; gender: string; isMarried: boolean; country: string; address: { city: string; street: string; pincode: string; } } export class country { id: string; name: string; constructor(id: string, name: string) { this.id = id; this.name = name; } } |
[tabby title=”app.component.html”]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | <form #contactForm="ngForm" (ngSubmit)="onSubmit(contactForm)"> <p> <label for="firstname">First Name </label> <input type="text" id="firstname" name="firstname" [(ngModel)]="contact.firstname"> </p> <p> <label for="lastname">Last Name </label> <input type="text" id="lastname" name="lastname" [(ngModel)]="contact.lastname"> </p> <p> <label for="email">Email </label> <input type="text" id="email" name="email" [(ngModel)]="contact.email"> </p> <p> <label for="gender">Geneder </label> <input type="radio" value="male" id="gender" name="gender" [(ngModel)]="contact.gender"> Male <input type="radio" value="female" id="gender" name="gender" [(ngModel)]="contact.gender"> Female </p> <p> <label for="isMarried">Married </label> <input type="checkbox" id="isMarried" name="isMarried" [(ngModel)]="contact.isMarried"> </p> <p> <label for="country">country </label> <select id="country" name="country" [(ngModel)]="contact.country"> <option [ngValue]="c.id" *ngFor="let c of countryList"> {{c.name}} </option> </select> </p> <div ngModelGroup="address"> <p> <label for="city">City</label> <input type="text" id="city" name="city" [(ngModel)]="contact.address.city"> </p> <p> <label for="street">Street</label> <input type="text" id="street" name="street" [(ngModel)]="contact.address.street"> </p> <p> <label for="pincode">Pin Code</label> <input type="text" id="pincode" name="pincode" [(ngModel)]="contact.address.pincode"> </p> </div> <p> <button type="submit">Submit</button> </p> <p> <button type="button" (click)="changeCountry()">Change Country</button> <button type="button" (click)="setDefaults()">Set Defaults</button> <button type="button" (click)="reset(contactForm)">Reset</button> </p> <b>valid</b> {{contactForm.valid}} <b>touched</b> {{contactForm.touched}} <b>pristine</b> {{contactForm.pristine}} <b>dirty</b> {{contactForm.dirty}} </form> |
[tabbyending]
Template reference variable
We have a #contactForm
reference variable, which is an instance of ngForm
.
1 2 3 | <form #contactForm="ngForm" (ngSubmit)="onSubmit(contactForm)"> |
We can get the reference to the #contactForm
in the app.component.ts
, using the viewchild
1 2 3 | @ViewChild('contactForm',null) contactForm: NgForm; |
Once we have the reference, we can use the setValue
method of the ngForm
to set the initial value
Set the default or initial value
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ngOnInit() { this.contact = { firstname: "Sachin", lastname: "Tendulkar", gender: "male", isMarried: true, country: "2", address: { city: "Mumbai", street: "Perry Cross Rd", pincode: "400050" } }; setTimeout(() => { this.contactForm.setValue(this.contact); }); } |
Note that we are using the setTimeout
That is because the form controls are yet initialized when the OnInit
is fired. We will get the following error message
There are no form controls registered with this group yet. If you’re using ngModel, you may want to check next tick (e.g. use setTimeout).
Set the value individually or dynamically
You can also set the value individually using the setValue
method of the individual FormControl
.
You will get the reference to the individual FormControl
from the controls
collection of the ngForm
. Once you get the reference use the setValue
on the FormControl
instance to change the value.
For Example, this code will change the country to India
1 2 3 4 5 | changeCountry() { this.contactForm.controls["country"].setValue("1"); } |
Call the changeCountry
method from the Template.
1 2 3 | <button type="button" (click)="changeCountry()">Change Country</button> |
Reset values
You can reset the form to empty value using the reset
or resetForm
method of the ngForm
. These also resets the form status like dirty
, valid
, pristine
& touched
, etc
1 2 3 4 5 | reset() { this.contactForm.reset(); } |
1 2 3 4 5 | resetForm() { this.contactForm.resetForm(); } |
Set Default Value
You can invoke the setValue
anytime to set the form back to the default value. This will set the entire form to the value held by the contact form.
1 2 3 4 5 | setDefaults() { this.contactForm.setValue(this.contact); } |
patch value
You can make use of the patchValue
to change the only few fields anytime. The control property of the ngForm
returns the reference to the top level FormGroup
. Then, you can make use of the patchValue
method to change only firstname
, lastname
& email
fields
1 2 3 4 5 6 7 8 9 10 11 12 | patchValue() { let obj = { firstname: "Rahul", lastname: "Dravid", }; this.contactForm.control.patchValue(obj); } |
Set value of nested FormGroup
You can update nested FormGroup
by getting a reference to the nested FormGroup
from the controls
collection of ngForm
.
1 2 3 4 5 6 7 8 9 10 11 12 | changeAddress() { let obj = { city: "Bangalore", street: "Brigade Road", pincode: "600100" }; let address= this.contactForm.controls["address"] as FormGroup address.patchValue(obj); } |
The complete code.
[tabby title=”app.component.ts”]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 | import { Component, ViewChild, ElementRef, OnInit } from '@angular/core'; import { NgForm, FormGroup } from '@angular/forms'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent implements OnInit { title = 'Template driven forms'; @ViewChild('contactForm', null) contactForm: NgForm; countryList: country[] = [ new country("1", "India"), new country('2', 'USA'), new country('3', 'England') ]; contact: contact; ngOnInit() { this.contact = { firstname: "Sachin", lastname: "Tendulkar", gender: "male", isMarried: true, country: "2", address: { city: "Mumbai", street: "Perry Cross Rd", pincode: "400050" } }; setTimeout(() => { this.contactForm.setValue(this.contact); }); } onSubmit() { console.log(this.contactForm.value); } setDefaults() { this.contactForm.setValue(this.contact); } changeCountry() { this.contactForm.controls["country"].setValue("1"); } patchValue() { let obj = { firstname: "Rahul", lastname: "Dravid", }; this.contactForm.control.patchValue(obj); } changeAddress() { let obj = { city: "Bangalore", street: "Brigade Road", pincode: "600100" }; let address= this.contactForm.controls["address"] as FormGroup address.patchValue(obj); } reset() { this.contactForm.reset(); } resetForm() { this.contactForm.resetForm(); } } export class contact { firstname: string; lastname: string; email: string; gender: string; isMarried: boolean; country: string; address: { city: string; street: string; pincode: string; } } export class country { id: string; name: string; constructor(id: string, name: string) { this.id = id; this.name = name; } } |
[tabby title=”app.component.html”]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | <form #contactForm="ngForm" (ngSubmit)="onSubmit(contactForm)"> <p> <label for="firstname">First Name </label> <input type="text" id="firstname" name="firstname" ngModel> </p> <p> <label for="lastname">Last Name </label> <input type="text" id="lastname" name="lastname" ngModel> </p> <p> <label for="email">Email </label> <input type="text" id="email" name="email" ngModel> </p> <p> <label for="gender">Geneder </label> <input type="radio" value="male" id="gender" name="gender" ngModel> Male <input type="radio" value="female" id="gender" name="gender" ngModel> Female </p> <p> <label for="isMarried">Married </label> <input type="checkbox" id="isMarried" name="isMarried" ngModel> </p> <p> <label for="country">country </label> <select id="country" name="country" ngModel> <option [ngValue]="c.id" *ngFor="let c of countryList"> {{c.name}} </option> </select> </p> <div ngModelGroup="address"> <p> <label for="city">City</label> <input type="text" id="city" name="city" ngModel> </p> <p> <label for="street">Street</label> <input type="text" id="street" name="street" ngModel> </p> <p> <label for="pincode">Pin Code</label> <input type="text" id="pincode" name="pincode" ngModel> </p> </div> <p> <button type="submit">Submit</button> </p> <p> <button type="button" (click)="changeCountry()">Change Country</button> <button type="button" (click)="setDefaults()">Set Defaults</button> <button type="button" (click)="patchValue()">Patch Value</button> <button type="button" (click)="changeAddress()">Change Address</button> <button type="button" (click)="reset()">Reset</button> <button type="button" (click)="resetForm()">Reset Form</button> </p> <b>valid</b> {{contactForm.valid}} <b>touched</b> {{contactForm.touched}} <b>pristine</b> {{contactForm.pristine}} <b>dirty</b> {{contactForm.dirty}} </form> |
[tabbyending]
Summary
In this tutorial, we learned how to set the form values in the template-driven forms. We can either use the setValue of the ngForm directive or use the two-way data binding.
The list of Article on Angular Forms
- Angular Forms Tutorial: Fundamental & Concepts
- Template Driven Forms in Angular
- Set Value in Template Driven forms in Angular
- Reactive Forms in Angular
- FormBuilder in Reactive Forms
- SetValue & PatchValue in Angular
- StatusChanges in Angular Forms
- ValueChanges in Angular Forms
- FormControl
- FormGroup
- FormArray Example
- Build Dynamic or Nested Forms using FormArray
- Validations in Reactive Forms in Angular
- Custom Validator in Reactive Forms
- Passing Parameter to Custom Validator in Reactive Forms
- Inject Service into Custom Validator
- Validation in Template Driven Forms
- Custom Validator in Template Driven Forms
HI Team , I don’t think its best way to initialize the template form using setTimeout method. can you please provide proper alternative solution to that.
With this tutorials I understand Angular better, thanks! But I would change in some moments quality of code. For example here in app.component.ts section you repeat code in ngOnInit which is in the setDefaults method
fantastic tutorials awsomeee…..
thank you soo much
GitHub/StackBlitz link for the repo please for better understanding?
First, I’d like to say that I think these tutorials are awesome.
BUT, when you change screens in mid-lesson to show another technique, it get CONFUSING.
Here you take l from the previous lesson’s “app.component.html from the angular template-driven forms tutorial.”
But you change it somehow and it’s not clear.
I think i need to create a whole new app to work with this “how-to-set-value-in-template-driven-forms-in-angular”.