FormBuilder In Reactive Forms

FormBuilder In Reactive Forms

In this article, we will learn about the how to use the FormBuilder to create a Form and add validation criteria. The Angular FormBuilder API simplifies the creation of reactive forms. FormGroups, nested FormGroups, FormArrays, and FormControls are all simple to add. It also enables us to configure the Validation rules for each control.

We recommend learning how to develop reactive forms if you're new to Reactive Forms.

What is FormBuilder

The FormBuilder is an Angular utility API for creating forms. It provides shortcuts for creating FormControl, FormGroup, and FormArray instances. It cuts down on the amount of code needed to create complex forms.

How to use FormBuilder

Import & inject FormBuilder API

To use the FormBuilder, we must first import it in our component.

import { FormBuilder } from '@angular/forms'

 Following that, we must inject it into our component class.
constructor(private formBuilder: FormBuilder) {
}

Finally, construct the FormModel using the group, array, and control methods.

FormGroup

To create the Form Group, we use the group method. As a key-value pair, we supply the group method a list of Form Controls, a Form Array, or another Form Group. The name of the FormControlFormGroup, or FormArray is the key. The control's configuration is the value.

We've added six form controls to the example below. The initial value, which we set to empty string, is the first argument to the FormControl.
this.contactForm = this.formBuilder.group({
  firstname: [''],
  lastname: [''],
  email: [''],
  gender: [''],
  isMarried: [''],
  country: [''],
});

Nested FormGroup

It's exactly as simple to make a Nested FormGroup. As demonstrated below, use the formbuilder.group method.
this.contactForm = this.formBuilder.group({
  firstname: [''],
  lastname: [''],
  email: [''],
  gender: [''],
  isMarried: [''],
  country: [''],
  address: this.formBuilder.group({
    city: [''],
    street: [''],
    pincode: ['']
  })
})

Validations

The list of sync validators is the FormControl second argument. The example below demonstrates how to add validators.
this.contactForm = this.formBuilder.group({
  firstname: ['', [Validators.required, Validators.minLength(10)]],
  lastname: ['', [Validators.required, Validators.maxLength(15), Validators.pattern("^[a-zA-Z]+$")]],
  email: ['', [Validators.required, Validators.email]],
  gender: ['', [Validators.required]],
  isMarried: ['', [Validators.required]],
  country: ['', [Validators.required]],
  address: this.formBuilder.group({
    city: ['', [Validators.required]],
    street: ['', [Validators.required]],
    pincode: ['', [Validators.required]],
  })
});

Example of FormBuilder

The Angular Reactive Forms article taught us how to create reactive forms.

Open the app.component.ts file and add the following code:
import { Component, ViewChild, ElementRef } from '@angular/core';
import { FormGroup, FormControl, Validators } from '@angular/forms'
import { FormBuilder } from '@angular/forms'
import { groupBy } from 'rxjs/internal/operators/groupBy';
 
 
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
 
  title = 'Angular Reactive forms';
 
  contactForm;
 
  constructor(private formBuilder: FormBuilder) {
 
 
 
    // this.contactForm = this.formBuilder.group({
    //   firstname: [''],
    //   lastname: [''],
    //   email: [''],
    //   gender: [''],
    //   isMarried: [''],
    //   country: [''],
    // });
 
    // this.contactForm = this.formBuilder.group({
    //   firstname: [''],
    //   lastname: [''],
    //   email: [''],
    //   gender: [''],
    //   isMarried: [''],
    //   country: [''],
    //   address: this.formBuilder.group({
    //     city: [''],
    //     street: [''],
    //     pincode: ['']
    //   })
    // });
 
    this.contactForm = this.formBuilder.group({
      firstname: ['', [Validators.required, Validators.minLength(10)]],
      lastname: ['', [Validators.required, Validators.maxLength(15), Validators.pattern("^[a-zA-Z]+$")]],
      email: ['', [Validators.required, Validators.email]],
      gender: ['', [Validators.required]],
      isMarried: ['', [Validators.required]],
      country: ['', [Validators.required]],
      address: this.formBuilder.group({
        city: ['', [Validators.required]],
        street: ['', [Validators.required]],
        pincode: ['', [Validators.required]],
      })
    });
  }
 
 
  get firstname() {
    return this.contactForm.get('firstname');
  }
 
  get lastname() {
    return this.contactForm.get('lastname');
  }
 
  get email() {
    return this.contactForm.get('email');
  }
 
  get gender() {
    return this.contactForm.get('gender');
  }
 
  get isMarried() {
    return this.contactForm.get('isMarried');
  }
 
  get country() {
    return this.contactForm.get('country');
  }
 
  get city() {
    return this.contactForm.get("address").get('city');
  }
 
  get street() {
    return this.contactForm.get("address").get('street');
  }
 
  get pincode() {
    return this.contactForm.get("address").get('pincode');
  }
 
 
  countryList: country[] = [
    new country("1", "India"),
    new country('2', 'USA'),
    new country('3', 'England')
  ];
 
  onSubmit() {
    console.log(this.contactForm.value);
  }
 
}
 
 
export class country {
  id: string;
  name: string;
 
  constructor(id: string, name: string) {
    this.id = id;
    this.name = name;
  }
}

Now, open the app.component.html file and add the following code:
<div style="float: left; width:50%;">
 
<form [formGroup]="contactForm" (ngSubmit)="onSubmit()" novalidate>
 
  <p>
    <label for="firstname">First Name </label>
    <input type="text" id="firstname" name="firstname" formControlName="firstname">
  </p>
 
  <div
    *ngIf="!firstname?.valid && (firstname?.dirty ||firstname?.touched)">
    <div [hidden]="!firstname.errors.required">
      First Name is required
    </div>
    <div [hidden]="!firstname.errors.minlength">
      Min Length is 10
    </div>
  </div>
 
  <p>
    <label for="lastname">Last Name </label>
    <input type="text" id="lastname" name="lastname" formControlName="lastname">
  </p>
 
  <div *ngIf="!lastname.valid && (lastname.dirty ||lastname.touched)">
    <div [hidden]="!lastname.errors.pattern">
      Only characters are allowed
    </div>
    <div [hidden]="!lastname.errors.maxLength">
      Max length allowed is {{lastname.errors.maxlength?.requiredLength}} 
    </div>
    <div [hidden]="!lastname.errors.required">
      Last Name is required
    </div>
  </div>
 
  <p>
    <label for="email">Email </label>
    <input type="text" id="email" name="email" formControlName="email">
  </p>
  <div *ngIf="!email.valid && (email.dirty ||email.touched)">
    <div [hidden]="!email.errors.required">
      email is required
    </div>
    <div [hidden]="!email.errors.email">
      invalid email id
    </div>
  </div>
 
 
  <p>
    <label for="gender">Geneder </label>
    <input type="radio" value="male" id="gender" name="gender" formControlName="gender"> Male
    <input type="radio" value="female" id="gender" name="gender" formControlName="gender"> Female
  </p>
  <div *ngIf="!gender.valid && (gender.dirty ||gender.touched)">
    <div [hidden]="!gender.errors.required">
      gender is required
    </div>
  </div>
 
  <p>
    <label for="isMarried">Married </label>
    <input type="checkbox" id="isMarried" name="isMarried" formControlName="isMarried">
  </p>
  <div *ngIf="!isMarried.valid && (isMarried.dirty ||isMarried.touched)">
    <div [hidden]="!isMarried.errors.required">
      isMarried is required
    </div>
  </div>
 
 
  <p>
    <label for="country">country </label>
    <select id="country" name="country" formControlName="country">
      <option [ngValue]="c.id" *ngFor="let c of countryList">
        {{c.name}}
      </option>
    </select>
  </p>
  <div *ngIf="!country.valid && (country.dirty ||country.touched)">
    <div [hidden]="!country.errors.required">
      country is required
    </div>
  </div>
 
  <div formGroupName="address">
 
    <div class="form-group">
      <label for="city">City</label>
      <input type="text" class="form-control" name="city" formControlName="city">
    </div>
    <div *ngIf="!city.valid && (city.dirty ||city.touched)">
      <div [hidden]="!city.errors.required">
        city is required
      </div>
    </div>
 
 
    <div class="form-group">
      <label for="street">Street</label>
      <input type="text" class="form-control" name="street" formControlName="street">
    </div>
    <div *ngIf="!street.valid && (street.dirty ||street.touched)">
      <div [hidden]="!street.errors.required">
        street is required
      </div>
    </div>
 
    <div class="form-group">
      <label for="pincode">Pin Code</label>
      <input type="text" class="form-control" name="pincode" formControlName="pincode">
    </div>
    <div *ngIf="!pincode.valid && (pincode.dirty ||pincode.touched)">
      <div [hidden]="!pincode.errors.required">
        pincode is required
      </div>
    </div>
 
  </div> 
 
  <p>
    <button type="submit" [disabled]="!contactForm.valid">Submit</button>
  </p>
 
</form>
 
</div>
 
<div style="float: right; width:50%;">
 
  <h3>Form Status</h3>
  <b>valid : </b>{{contactForm.valid}}
  <b>invalid : </b>{{contactForm.invalid}}
  <b>touched : </b>{{contactForm.touched}}
  <b>untouched : </b>{{contactForm.untouched}}
  <b>pristine : </b>{{contactForm.pristine}}
  <b>dirty : </b>{{contactForm.dirty}}
  <b>disabled : </b>{{contactForm.disabled}}
  <b>enabled : </b>{{contactForm.enabled}}
 
  <h3>Form Value</h3>
  {{contactForm.value |json}}
 
</div>

Conclusion

The FormBuilder API makes it easy to interact with Angular reactive forms. To create our    FormModel, we can use the group, array, and control methods. FormBuilder cuts down on the amount of code needed to create sophisticated forms.

I hope this article helps you and you will like it.👍

If you have any doubt or confusion then free to ask in comment section.

Post a Comment

Previous Post Next Post