Angular Reactive Forms: Dynamic Field Management with FormArray and FormRecord
In Angular reactive forms, adding or removing fields dynamically can be challenging. Fortunately, FormArray
and FormRecord
provide an elegant solution.
What are FormArray and FormRecord?
FormArray
and FormRecord
are two essential classes in Angular's reactive forms library.
FormArray
FormArray
is a class that represents an array of FormControl
instances. It allows you to create, update, and manage a collection of form controls.
Key Features of FormArray:
- Creates an array of
FormControl
instances - Supports adding, removing, and replacing controls
- Provides methods for iterating and accessing controls
Example: Dynamic Phone Numbers
// Component
phoneNumbersForm = new FormGroup({
phoneNumbers: new FormArray([
new FormControl(''),
]),
});
addPhoneNumber() {
this.phoneNumbersForm.controls.phoneNumbers.push(new FormControl(''));
}
removePhoneNumber(index: number) {
this.phoneNumbersForm.controls.phoneNumbers.removeAt(index);
}
<!-- Template -->
<form [formGroup]="phoneNumbersForm">
<div formArrayName="phoneNumbers">
<div *ngFor="let phoneNumber of phoneNumbersForm.controls.phoneNumbers.controls; let i = index">
<input [formControlName]="i" placeholder="Phone Number">
<button (click)="removePhoneNumber(i)">Remove</button>
</div>
</div>
<button (click)="addPhoneNumber()">Add Phone Number</button>
</form>
FormRecord
FormRecord
is a class that represents a record of FormControl
instances. It allows you to create, update, and manage a collection of form controls with unique keys.
Key Features of FormRecord:
- Creates a record of
FormControl
instances with unique keys - Supports adding, removing, and replacing controls
- Provides methods for iterating and accessing controls
Example: Dynamic Address
// Component
addressForm = new FormRecord({});
newFieldName: any;
get addressFormKeys() { return Object.keys(this.addressForm.controls) }
addAddressField(fieldName: string) {
this.addressForm.addControl(fieldName, new FormControl(''));
this.newFieldName = ''
}
removeAddressField(fieldName: string) {
this.addressForm.removeControl(fieldName);
}
getAddressField() {
console.log(this.addressForm.value);
}
<!-- Template -->
<form [formGroup]="addressForm">
<div formRecordName="address">
<div *ngFor="let fieldName of addressFormKeys">
<p><b>{{ fieldName }}</b>
<input [formControlName]="fieldName" placeholder="{{ fieldName }}">
<button (click)="removeAddressField(fieldName)">Remove</button>
</p>
</div>
</div>
<button (click)="getAddressField()">Get All Address Field</button>
</form>
<input placeholder="New Field Name" [(ngModel)]="newFieldName">
<button (click)="addAddressField(newFieldName)">Add Address Field</button>
Conclusion
FormArray
and FormRecord
provide a flexible way to dynamically add or remove fields in Angular reactive forms.
Best Practices
- Use
FormArray
for arrays of identical fields. - Use
FormRecord
for objects with varying field names. - Always validate user input when dynamically adding fields.
Stay tuned for more Angular form tutorials!