Introduction
In Angular applications, we use Reactive forms to create the form modal for our angular application. Creating forms using FormGroup and FormControl is very repetitive as we create the instances of group and FormControl manually every time we create the new fields or group.
So to avoid this multiple repetitive process Angular provides a helper service which in turn provides methods in generating forms controls. We will create the forms controls just like the previous generation of new FormControls but in less code.
FormBuilder is a service, so we have to import the service and inject it into the constructor.
Implementation
Let us create a simple application that utilizes Reactive forms.
Create a TestApp project using Angular CLI.
Create a test component which will contain the forms and related field.
Open test.component.ts and add the below contents:
- import { Component, OnInit } from '@angular/core';
- import { FormBuilder } from '@angular/forms';
-
- @Component({
- selector: 'app-test',
- templateUrl: './test.component.html',
- styleUrls: ['./test.component.css']
- })
- export class TestComponent implements OnInit {
-
- registrationForm: any;
- graduationData: any;
- pgData: any;
- sampleData: any;
- constructor(private fb: FormBuilder) {
- this.registrationForm = this.fb.group({
- userName: ['Irshad'],
- password: ['password'],
- email: ['[email protected]'],
- phone: ['9999999999'],
- address: this.fb.group({
- country: ['India'],
- state: ['UP'],
- city: ['Allahabad'],
- pin: ['211001']
- }),
- qualification: this.fb.group({
- graduation: ['BCA'],
- pg: ['MCA']
- })
- });
- }
-
- ngOnInit() {
- this.graduationData = ['Select', 'BCA', 'BBA', 'BE', 'B.Tech', 'B.Sc'];
- this.pgData = ['Select', 'MCA', 'MBA', 'M.Tech', 'M.Sc'];
- }
- }
Open test.component.html and edit with below contents:
- <div class="container-fluid">
- <h3>Registration Form</h3>
- <form [formGroup]="registrationForm">
- <div class="row">
- <div class="col-sm-6">
- <div class="form-group">
- <label>UserName</label>
- <input formControlName="userName" type="text" class="form-control">
- </div>
- </div>
- <div class="col-sm-6">
- <div class="form-group">
- <label>Password</label>
- <input formControlName="password" type="Password" class="form-control">
- </div>
- </div>
- </div>
- <div class="row">
- <div class="col-sm-6">
- <div class="form-group">
- <label>Email Address</label>
- <input formControlName="email" type="email" class="form-control">
- </div>
- </div>
- <div class="col-sm-6">
- <div class="form-group">
- <label>Phone</label>
- <input formControlName="phone" type="Phone" class="form-control">
- </div>
- </div>
- </div>
- <div formGroupName="address">
- <div class="row">
- <div class="col-sm-6">
- <div class="form-group">
- <label>Country</label>
- <input formControlName="country" type="text" class="form-control">
- </div>
- </div>
- <div class="col-sm-6">
- <div class="form-group">
- <label>State</label>
- <input formControlName="state" type="text" class="form-control">
- </div>
- </div>
- </div>
- <div class="row">
- <div class="col-sm-6">
- <div class="form-group">
- <label>City</label>
- <input formControlName="city" type="text" class="form-control">
- </div>
- </div>
- <div class="col-sm-6">
- <div class="form-group">
- <label>Pin</label>
- <input formControlName="pin" type="text" class="form-control">
- </div>
- </div>
- </div>
- </div>
- <div formGroupName="qualification">
- <div class="row">
- <div class="col-sm-6">
- <div class="form-group">
- <label>Graduation</label>
- <select formControlName="graduation" class="form-control">
- <option *ngFor="let value of graduationData" [ngValue]="value">{{value}}</option>
- </select>
- </div>
- </div>
- <div class="col-sm-6">
- <div class="form-group">
- <label>PG</label>
- <select formControlName="pg" class="form-control">
- <option *ngFor="let value of pgData" [ngValue]="value">{{value}}</option>
- </select>
- </div>
- </div>
- </div>
- </div>
- <div class="row">
- <div class="col-sm-6">
- <button class="btn btn-primary" type="submit">Register</button>
- </div>
- </div>
- </form>
- {{registrationForm.value | json}}
- </div>
Run the application:
You can see the form has been created and values are filled that we have given as default.
Using setValue and patchValue methods:
Open test.component.ts and edit with below contents:
- import { Component, OnInit } from '@angular/core';
- import { FormBuilder } from '@angular/forms';
-
- @Component({
- selector: 'app-test',
- templateUrl: './test.component.html',
- styleUrls: ['./test.component.css']
- })
-
- export class TestComponent implements OnInit {
- registrationForm: any;
- graduationData: any;
- pgData: any;
- sampleData: any;
- constructor(private fb: FormBuilder) {
- this.registrationForm = this.fb.group({
- userName: [''],
- password: [''],
- email: [''],
- phone: [''],
- address: this.fb.group({
- country: [''],
- state: [''],
- city: [''],
- pin: ['']
- }),
- qualification: this.fb.group({
- graduation: [''],
- pg: ['']
- })
- });
- }
-
- ngOnInit() {
- this.graduationData = ['Select', 'BCA', 'BBA', 'BE', 'B.Tech', 'B.Sc'];
- this.pgData = ['Select', 'MCA', 'MBA', 'M.Tech', 'M.Sc'];
- this.sampleData = {
- userName: 'Irshad',
- password: 'password',
- email: '[email protected]',
- phone: '9999999999',
- address: {
- country: 'India',
- state: 'UP',
- city: 'Allahabad',
- pin: '211001'
- },
- qualification: {
- graduation: 'B.Sc',
- pg: 'MCA'
- }
- };
- setTimeout(() => this.registrationForm.setValue(this.sampleData), 5000);
- }
- }
Run the application and after 5 seconds the sampleData values will be set to the form controls. setValue will work same whether we use formBuilder service or not. It will throw an error if any field is not passed in its control mapping. So we have to follow its strict rule by providing all the properties that is going to match its controls.
Open test.component.ts and change the setTimeout statement by replacing setValue to patchValue.
- setTimeout(() => this.registrationForm.patchValue(this.sampleData), 5000);
Now you can skip giving any field control value from the sampleData object. It will not throw error and set the values that are available.
So the sampleData
- this.sampleData = {
- userName: 'Irshad',
- password: 'password',
- email: '[email protected]',
- phone: '9999999999'
- };
Is correct in case of patchValue but incorrect in case of setValue method.\
Also if we are giving the sampleData as below:
- this.sampleData = {
- firstName: 'Mohammad',
- lastName: 'Irshad',
- userName: 'Irshad',
- fullName: 'Mohammad Irshad',
- password: 'password',
- email: '[email protected]',
- phone: '9999999999'
- };
This will be correct in the case of patchValue method. Doesn’t matter if we supply the values (firstName, lastName, fullName) that are not there in the formGroup.
But it will throw an error in case of setValue by giving an error message that ‘firstName’ control is not found.
Summary
In this article, we learned about FormBuilder Service in Angular and how to use these services in the code examples.