Home Angular Tutorials using Angular formBuilder and formGroup

using Angular formBuilder and formGroup

by aouidane.med.amine
44,626 views 30 min read

In this Angular tutorial, we will focus on how to handle the user Input via the use of angular formBuilder and formGroup.

Angular forms are essential for any web application because they are used for everything from a simple login to much more complex use cases.   

Angular supports two approaches , the template-driven forms and the reactive forms.

In this tutorial we are going to use the reactive forms approach to use angular formBuilder and fromGroup to build our forms. 

Table of Contents

What is Angular formBuilder ?

We can define the angular formbuilder as a helper or a tool that allows us to create formgroup , FormArray and simple formControl.

using angular formBuilder helps us to create complex forms swiftly with the minimum of code.

How to use Angular formBuilder ?

import and inject the formBuilder service

Importing formBuilder is not enough to use the form Apis such as formControl , formGroup and formArray.

To do that , we only need to import the class FormBuilder from @angular/forms to the component and inject it into the constructor :

				
					import {Component} from '@angular/core';
import {FormBuilder} from "@angular/forms";

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {

  constructor(private formBuilder: FormBuilder) {
  }
				
			

What is Angular FormGroup ?

Angular formGroup is a method that allows us to create a group of controls, so we can have a list of simple formControls and formArray and even a list of formGroup.

the formGroup accepts an object , that means , we will have a key-value pair.

The key is the name of the control ( exp : name , phone ..) and the value is the configuration of the control which could be a simple formControl, formArray or a formGroup

How to use Angular FormGroup ?

importing ReactiveFormModule

Importing fromBuilder is not enough to use the form Apis such as formControl , formGroup and formArray.

To do that , we only need to import ReactiveFormModule in the appModule.

				
					import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import {ReactiveFormsModule} from "@angular/forms";

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    ReactiveFormsModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

				
			

Using Simple formGroup

Create formGroup

To create a formGroup w only need to create a new instance of the class formGroup and pass the object configuration as argument.

we can also init the value of the formControl.

				
					   this.userForm = new FormGroup({
      'name': new FormControl(),
      'webSite': new FormControl('XperTuto.com'),
      'technologie': new FormControl('Angular'),
    });
				
			

formGroup get value

Now we need to get the values of the form , to do that we need to get the control and then we get the value.

there is two ways to do that :

using the getRowValue() method , it is used when we need to get all the data of the formGroup :

				
					  const allData = this.userForm.getRawValue();
				
			

using the accessor of the form control value , used when we need to get the value of one only formControl and not all the formGroup :

				
					 const name =  this.userForm.controls['name'].value
				
			

Using nested formGroup

Create nested formGroup

the nested formGroup , is a simple formGroup that containing others formGroup and formArray, it is used to handle more complex forms :

				
					  this.userForm = new FormGroup({
      'name': new FormControl(),
      'webSite': new FormControl('XperTuto.com'),
      'technologie': new FormGroup({
        'front': new FormControl('Angular'),
        'back': new FormControl('NodeJs'),
        'mobile': new FormControl('Android'),
      })
    });
				
			

we need to update also our Form in the html , by adding a new bloc containing the formGroupName

				
					<form [formGroup]="userForm">
  Name: <input formControlName="name" placeholder="name">
  WebSite: <input formControlName="webSite" placeholder="webSite">
  <div formGroupName="Technologie">
    <h2>Technologies:</h2>
    <input formControlName="front" placeholder="front">
    <input formControlName="back" placeholder="back">
    <input formControlName="mobile" placeholder="mobile">
  </div>

  <button (click)="getFormData()">Submit</button>
</form>

				
			

Get nested formGroup value

getting the value of a nested formGroup is a little bit different to a normal formGroup , meanwhile we keep the same regular concept , we always need to get the formControl object and then we get the value

				
					const frontValue = this.userForm.get(['technologie','front']).value;

// OR 

const frontValue = this.userForm.get('technologie.front').value;
				
			

Using formControl validators

get and set form validators

when we build a form in our application , we need also to handle the form errors like this :

				
					    this.userForm = new FormGroup({
      'name': new FormControl('default name',Validators.required),
      'webSite': new FormControl('XperTuto.com', Validators.required),
      'technologie': new FormGroup({
        'front': new FormControl('', Validators.required),
        'back': new FormControl('',Validators.required),
        'mobile': new FormControl('',Validators.required)
      })
    })
				
			

In your html file , you can add the validation message also you can disable the submit button if the form is not valid.

				
					  Name: <input formControlName="name">
  <div class="notification">
    <span *ngIf="userForm?.controls['name']?.errors?.required">
      the name field is required
    </span>
  </div>
				
			

Disable the submit button if the form is not valid

				
					  <button (click)="getFormData()" [disabled]="!userForm.valid">Submit</button>
				
			

Example : Angular formBuilder and formGroup Application

Now, let’s put all together  :

app.component.ts

				
					import {Component, OnInit} from '@angular/core';
import {FormBuilder, FormControl, FormGroup, Validators} from "@angular/forms";

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {

  userForm: FormGroup | any;

  constructor(private formBuilder: FormBuilder) {
  }

  ngOnInit() {
    this.userForm = new FormGroup({
      'name': new FormControl('default name', Validators.required),
      'webSite': new FormControl('XperTuto.com', Validators.required),
      'technologie': new FormGroup({
        'front': new FormControl('', Validators.required),
        'back': new FormControl('', Validators.required),
        'mobile': new FormControl('', Validators.required)
      })
    })

    this.formBuilder.group(this.userForm);
  }

  getFormData(): void {
    let allData = this.userForm?.getRawValue();
    // get form data and call your API
  }
}

				
			

app.component.html

				
					<form [formGroup]="userForm">
  Name: <input formControlName="name">
  <div class="notification">
    <span *ngIf="userForm?.get('name')?.errors?.required">
      the name field is required
    </span>
  </div>
  WebSite: <input formControlName="webSite">
  <div class="notification">
    <span *ngIf="userForm?.get('webSite')?.errors?.required">
      the webSite field is required
    </span>
  </div>

  <div formGroupName="technologie">
    <h2>Technologies:</h2>
    <input formControlName="front">
    <div class="notification">
    <span *ngIf="userForm?.get('technologie.front')?.errors?.required">
      the front field is required
    </span>
    </div>

    <input formControlName="back">
    <div class="notification">
    <span *ngIf="userForm?.get('technologie.back')?.errors?.required">
      the back field is required
    </span>
    </div>

    <input formControlName="mobile">
    <div class="notification">
    <span *ngIf="userForm?.get('technologie.mobile')?.errors?.required">
      the mobile field is required
    </span>
    </div>
  </div>
  <button (click)="getFormData()" [disabled]="!userForm.valid">Submit</button>
</form>


				
			

app.module.ts

				
					import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import {ReactiveFormsModule} from "@angular/forms";

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    ReactiveFormsModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

				
			

References

Clone and Run the project

To download and run the example, please follow the steps :

1- Clone the source code from XperTuto git repository using the following command : 

git clone https://github.com/www-xperTuto-com/formBuilder_and_formGroup.git

2- Install the node dependencies using NPM command line  : npm install

3- Run the application using the following command : ng serve 

4- Access to the project through the URL : http://localhost:4200 

Read More About Angular Forms :

Recapitulation

In this tutorial we have seen how to use angular formBuilder and formGroup to create and handle simple or complex forms.

we also seen how to  update a simple formGroup to create nested formGroup and get the needed values and check the difference between a simple formGroup and nested formGroup.

Finally w have seen how to control the form input using the angular form validator that enable us to show the error notifications to the user and disable the submit form if the form is not yet valid.

I hope you enjoy reading this Tutorial.

You may also like