Swiftorial Logo
Home
Swift Lessons
Matchups
CodeSnaps
Tutorials
Career
Resources
FormBuilder Service in Angular

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 *