Nested FormGroups

Compose Forms From Smaller Forms

Nested FormGroups

A FormGroup can contain another FormGroup. This mirrors the shape of nested data so your form value lines up with your API payload.

4 min read Level 2/5 #angular#forms#structure
What you'll learn
  • Nest a FormGroup
  • Bind with formGroupName
  • Read nested values

Real-world forms have structure. A user has a name and an address; an address has a city, postcode, and country. Nested form groups let your form mirror that.

Defining a Nested Group

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

@Component({
  selector: 'app-profile',
  standalone: true,
  imports: [ReactiveFormsModule],
  template: `...`,
})
export class ProfileComponent {
  private fb = inject(FormBuilder);

  form = this.fb.group({
    name: ['', Validators.required],
    address: this.fb.group({
      city: ['', Validators.required],
      zip: '',
      country: 'US',
    }),
  });
}

form.value will be { name, address: { city, zip, country } } — exactly the shape your API probably wants.

Binding in the Template

Use formGroupName to enter the nested group, then formControlName for each field inside.

<form [formGroup]="form">
  <input formControlName="name" placeholder="Name" />

  <fieldset formGroupName="address">
    <legend>Address</legend>
    <input formControlName="city" placeholder="City" />
    <input formControlName="zip" placeholder="Zip" />
    <input formControlName="country" placeholder="Country" />
  </fieldset>
</form>

Accessing Nested Controls

You can dot into typed forms directly.

this.form.controls.address.controls.city.setValue('Berlin');

this.form.controls.address.valueChanges.subscribe(addr => {
  console.log('address changed', addr);
});

form.get('address.city') works too but loses the strong typing — prefer the property chain.

Mixing With FormArray

A nested group can sit inside a FormArray, and a FormArray can live inside a group. That is how you build forms like “list of users, each with a list of skills” without any extra plumbing.

Form Status & Error Display →