0
0
AngularHow-ToBeginner · 3 min read

How to Use FormArray for Dynamic Fields in Angular

In Angular, use FormArray inside a reactive form to handle dynamic fields by adding or removing FormControl or FormGroup instances. Initialize FormArray in your component, then use methods like push() and removeAt() to update fields dynamically in the template.
📐

Syntax

The FormArray is a collection of FormControl or FormGroup instances. You create it inside a FormGroup and manage its controls dynamically.

  • new FormArray([]): Creates an empty array of controls.
  • formArray.push(new FormControl('')): Adds a new control.
  • formArray.removeAt(index): Removes control at given index.
  • formArray.controls: Access all controls in the array.
typescript
import { FormGroup, FormArray, FormControl } from '@angular/forms';

this.form = new FormGroup({
  items: new FormArray([]) // initialize empty FormArray
});

// Add a new control
(this.form.get('items') as FormArray).push(new FormControl(''));

// Remove control at index
(this.form.get('items') as FormArray).removeAt(0);
💻

Example

This example shows a form where users can add or remove email fields dynamically using FormArray. The form updates as fields change.

typescript
import { Component } from '@angular/core';
import { FormGroup, FormArray, FormControl, Validators } from '@angular/forms';

@Component({
  selector: 'app-dynamic-form',
  template: `
    <form [formGroup]="form">
      <div formArrayName="emails">
        <div *ngFor="let emailCtrl of emails.controls; let i = index">
          <input [formControlName]="i" placeholder="Email {{i + 1}}" />
          <button type="button" (click)="removeEmail(i)">Remove</button>
        </div>
      </div>
      <button type="button" (click)="addEmail()">Add Email</button>
      <pre>{{ form.value | json }}</pre>
    </form>
  `
})
export class DynamicFormComponent {
  form = new FormGroup({
    emails: new FormArray([
      new FormControl('', [Validators.required, Validators.email])
    ])
  });

  get emails() {
    return this.form.get('emails') as FormArray;
  }

  addEmail() {
    this.emails.push(new FormControl('', [Validators.required, Validators.email]));
  }

  removeEmail(index: number) {
    this.emails.removeAt(index);
  }
}
Output
<form> with dynamic email input fields and buttons to add or remove fields; below the form, JSON shows current form values like {"emails":["user1@example.com","user2@example.com"]}</form>
⚠️

Common Pitfalls

  • Not casting the FormArray when accessing it causes TypeScript errors; always cast with as FormArray.
  • Forgetting to update the template with formArrayName and formControlName leads to binding errors.
  • Not initializing the FormArray with at least one control can cause empty UI.
  • Removing controls without checking index can cause runtime errors.
typescript
/* Wrong: Accessing FormArray without casting */
const emails = this.form.get('emails');
emails.push(new FormControl('')); // Error: Property 'push' does not exist

/* Right: Cast to FormArray */
const emails = this.form.get('emails') as FormArray;
emails.push(new FormControl(''));
📊

Quick Reference

Use this quick guide to manage dynamic fields with FormArray:

ActionCode ExampleDescription
Create FormArraynew FormArray([])Start with an empty array of controls.
Add ControlformArray.push(new FormControl(''))Add a new form control dynamically.
Remove ControlformArray.removeAt(index)Remove control at specific index.
Get ControlsformArray.controlsAccess all controls in the array.
Cast FormArrayconst arr = form.get('name') as FormArrayCast to FormArray for methods access.

Key Takeaways

Use FormArray inside a FormGroup to manage dynamic form fields in Angular.
Always cast the result of form.get() to FormArray to access its methods safely.
Use push() to add and removeAt() to remove controls dynamically.
Bind FormArray in the template with formArrayName and formControlName for each control.
Initialize FormArray with at least one control to avoid empty UI issues.