Sitemap

Angular FormBuilder

What is FormBuilder?

--

Press enter or click to view image in full size

FormBuilder is a helper service in Angular’s Reactive Forms module that provides syntactic sugar for creating instances of FormGroup, FormControl, and FormArray. It simplifies form creation by reducing boilerplate code.

Why Use FormBuilder?

  1. Cleaner Syntax: Less verbose than manually creating FormGroup/FormControl instances
  2. Improved Readability: More declarative approach to form creation
  3. Consistency: Standardized way to create forms across your application
  4. Maintainability: Easier to modify complex forms

How to Use FormBuilder

1. Basic Usage

First, import and inject the FormBuilder service

import { FormBuilder } from '@angular/forms';

constructor(private fb: FormBuilder) { }

2. Creating Form Controls

Without FormBuilder

import { FormGroup, FormControl } from '@angular/forms';

profileForm = new FormGroup({
firstName: new FormControl(''),
lastName: new FormControl(''),
email: new FormControl('')
});

Get The Frontend Fuel’s stories in your inbox

Join Medium for free to get updates from this writer.

With FormBuilder

profileForm = this.fb.group({
firstName: [''],
lastName: [''],
email: ['']
});

3. Adding Validators

loginForm = this.fb.group({
username: ['', [Validators.required, Validators.minLength(4)]],
password: ['', [Validators.required, Validators.minLength(8)]]
});

4. Nested Form Groups

userForm = this.fb.group({
personalInfo: this.fb.group({
firstName: [''],
lastName: ['']
}),
address: this.fb.group({
street: [''],
city: ['']
})
});

5. Form Arrays

skillsForm = this.fb.group({
skills: this.fb.array([
this.fb.control('')
])
});

Complete Example

import { Component } from '@angular/core';
import { FormBuilder, FormArray, Validators } from '@angular/forms';

@Component({
selector: 'app-user-profile',
template: `
<form [formGroup]="profileForm" (ngSubmit)="onSubmit()">
<div>
<label>First Name:</label>
<input formControlName="firstName">
<div *ngIf="profileForm.get('firstName').invalid && profileForm.get('firstName').touched">
First name is required
</div>
</div>

<div>
<label>Last Name:</label>
<input formControlName="lastName">
</div>

<div formGroupName="address">
<h3>Address</h3>
<div>
<label>Street:</label>
<input formControlName="street">
</div>
<div>
<label>City:</label>
<input formControlName="city">
</div>
</div>

<div formArrayName="skillset">
<h3>Skills</h3>
<button type="button" (click)="addSkill()">Add Skill</button>
<div *ngFor="let skill of skillset.controls; let i=index" [formGroupName]="i">
<div>
<label>Skill Name:</label>
<input formControlName="name" placeholder="e.g., Angular">
<div *ngIf="getSkillControl(i, 'name').invalid && getSkillControl(i, 'name').touched">
Skill name is required
</div>
</div>
<div>
<label>Proficiency:</label>
<select formControlName="proficiency">
<option value="beginner">Beginner</option>
<option value="intermediate">Intermediate</option>
<option value="advanced">Advanced</option>
<option value="expert">Expert</option>
</select>
</div>
<div>
<label>Years of Experience:</label>
<input type="number" formControlName="years" min="0" max="50">
</div>
<button type="button" (click)="removeSkill(i)">Remove</button>
<hr>
</div>
</div>

<button type="submit" [disabled]="!profileForm.valid">Submit</button>
</form>
`
})
export class UserProfileComponent {
profileForm = this.fb.group({
firstName: ['', Validators.required],
lastName: [''],
address: this.fb.group({
street: [''],
city: ['']
}),
skillset: this.fb.array([
this.createSkill()
])
});

constructor(private fb: FormBuilder) { }

// Getter for skillset FormArray
get skillset(): FormArray {
return this.profileForm.get('skillset') as FormArray;
}

// Helper to create a skill FormGroup
createSkill(): FormGroup {
return this.fb.group({
name: ['', Validators.required],
proficiency: ['intermediate'],
years: [1, [Validators.min(0), Validators.max(50)]]
});
}

// Helper to get a specific control within a skill
getSkillControl(index: number, controlName: string) {
return this.skillset.at(index).get(controlName);
}

// Add a new skill
addSkill() {
this.skillset.push(this.createSkill());
}

// Remove a skill
removeSkill(index: number) {
this.skillset.removeAt(index);
// Ensure at least one skill remains
if (this.skillset.length === 0) {
this.addSkill();
}
}

onSubmit() {
console.log('Form submitted:', this.profileForm.value);
// Process form data here
}
}

When to Use FormBuilder

  • For any non-trivial reactive form in Angular
  • When you have multiple forms in your application
  • When you need to create forms dynamically
  • When you want cleaner, more maintainable form code

FormBuilder is the recommended way to create reactive forms in Angular applications as it provides a cleaner and more maintainable approach to form creation.

--

--