FormBuilder Service in Angular
The FormBuilder service in Angular provides a convenient way to create and manage reactive forms. This tutorial covers the basics of the FormBuilder service and how to use it effectively in your Angular applications.
What is the FormBuilder Service?
The FormBuilder service is an injectable service that simplifies the creation of FormControl, FormGroup, and FormArray instances in reactive forms. It reduces the boilerplate code needed to set up reactive forms.
Setting Up FormBuilder
To use the FormBuilder service, you need to import it and inject it into your component:
// app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { ReactiveFormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule, ReactiveFormsModule],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
// app.component.ts
import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
userForm: FormGroup;
constructor(private fb: FormBuilder) {
this.userForm = this.fb.group({
name: ['', Validators.required],
email: ['', [Validators.required, Validators.email]]
});
}
onSubmit() {
console.log('Form submitted!', this.userForm.value);
}
}
// app.component.html
<form [formGroup]="userForm" (ngSubmit)="onSubmit()">
<div>
<label for="name">Name</label>
<input type="text" id="name" formControlName="name">
<div *ngIf="userForm.get('name').invalid && userForm.get('name').touched">Name is required</div>
</div>
<div>
<label for="email">Email</label>
<input type="email" id="email" formControlName="email">
<div *ngIf="userForm.get('email').invalid && userForm.get('email').touched">Enter a valid email</div>
</div>
<button type="submit" [disabled]="userForm.invalid">Submit</button>
</form>
Creating Nested FormGroups
The FormBuilder service makes it easy to create nested FormGroups:
// app.component.ts
import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
userForm: FormGroup;
constructor(private fb: FormBuilder) {
this.userForm = this.fb.group({
name: ['', Validators.required],
email: ['', [Validators.required, Validators.email]],
address: this.fb.group({
street: [''],
city: [''],
state: ['']
})
});
}
onSubmit() {
console.log('Form submitted!', this.userForm.value);
}
}
// app.component.html
<form [formGroup]="userForm" (ngSubmit)="onSubmit()">
<div>
<label for="name">Name</label>
<input type="text" id="name" formControlName="name">
<div *ngIf="userForm.get('name').invalid && userForm.get('name').touched">Name is required</div>
</div>
<div>
<label for="email">Email</label>
<input type="email" id="email" formControlName="email">
<div *ngIf="userForm.get('email').invalid && userForm.get('email').touched">Enter a valid email</div>
</div>
<div formGroupName="address">
<label for="street">Street</label>
<input type="text" id="street" formControlName="street">
<label for="city">City</label>
<input type="text" id="city" formControlName="city">
<label for="state">State</label>
<input type="text" id="state" formControlName="state">
</div>
<button type="submit" [disabled]="userForm.invalid">Submit</button>
</form>
Using FormArray
The FormBuilder service also simplifies creating and managing FormArrays:
// app.component.ts
import { Component } from '@angular/core';
import { FormBuilder, FormGroup, FormArray, Validators } from '@angular/forms';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
userForm: FormGroup;
constructor(private fb: FormBuilder) {
this.userForm = this.fb.group({
name: ['', Validators.required],
email: ['', [Validators.required, Validators.email]],
phones: this.fb.array([
this.fb.control('')
])
});
}
get phones() {
return this.userForm.get('phones') as FormArray;
}
addPhone() {
this.phones.push(this.fb.control(''));
}
onSubmit() {
console.log('Form submitted!', this.userForm.value);
}
}
// app.component.html
<form [formGroup]="userForm" (ngSubmit)="onSubmit()">
<div>
<label for="name">Name</label>
<input type="text" id="name" formControlName="name">
<div *ngIf="userForm.get('name').invalid && userForm.get('name').touched">Name is required</div>
</div>
<div>
<label for="email">Email</label>
<input type="email" id="email" formControlName="email">
<div *ngIf="userForm.get('email').invalid && userForm.get('email').touched">Enter a valid email</div>
</div>
<div formArrayName="phones">
<div *