Angular course · Module 8: Forms
FormArray - Dynamic Fields
FormArray allows dynamic addition and removal of fields - like adding new techniques to a samurai's arsenal!
import { FormArray, FormBuilder, FormGroup } from '@angular/forms';
interface SkillForm {
name: FormControl<string>;
level: FormControl<number>;
}
@Component({
template: `
<form [formGroup]="samuraiForm" (ngSubmit)="onSubmit()">
<input formControlName="name" placeholder="Samurai name">
<h3>Skills</h3>
<div formArrayName="skills">
@for (skill of skills.controls; track $index; let i = $index) {
<div [formGroupName]="i" class="skill-row">
<input formControlName="name" placeholder="Skill name">
<input formControlName="level" type="number" placeholder="Level">
<button type="button" (click)="removeSkill(i)">×</button>
</div>
}
</div>
<button type="button" (click)="addSkill()">Add skill</button>
<button type="submit">Save</button>
</form>
`
})
export class DynamicFormComponent {
private fb = inject(FormBuilder);
samuraiForm = this.fb.group({
name: ['', Validators.required],
skills: this.fb.array<FormGroup<SkillForm>>([])
});
// Getter for easy access
get skills(): FormArray<FormGroup<SkillForm>> {
return this.samuraiForm.get('skills') as FormArray;
}
addSkill(): void {
const skillGroup = this.fb.group({
name: ['', Validators.required],
level: [1, [Validators.min(1), Validators.max(10)]]
});
this.skills.push(skillGroup);
}
removeSkill(index: number): void {
this.skills.removeAt(index);
}
onSubmit(): void {
if (this.samuraiForm.valid) {
console.log(this.samuraiForm.value);
// { name: 'Musashi', skills: [{ name: 'Kendo', level: 5 }, ...] }
}
}
}Initialization with Data
loadSamurai(samurai: Samurai): void {
// Reset and set simple fields
this.samuraiForm.patchValue({
name: samurai.name
});
// Clear and add skills
this.skills.clear();
samurai.skills.forEach(skill => {
this.skills.push(this.fb.group({
name: [skill.name, Validators.required],
level: [skill.level]
}));
});
}Docs entries used in this lesson
Spotted a mistake in this lesson?
Check yourself
Answer the questions from this lesson. Pick an answer to see right away whether it is correct.
1. What is FormArray used for?
2. Which method do you use to add a new control to the end of a FormArray?
These are 2 of 3 questions for this lesson. Solve the rest in the game.
Hands-on tasks in the game
- Code editor
Complete the form with a dynamic list of samurai skills.
- Horizontal ordering
Arrange the tokens of the loop header iterating over FormArray controls (one line): @for (skill of skills.controls; track $index)
- Vertical ordering
Order the steps for re-populating a FormArray with samurai data (execution order inside the method, line by line).
- Click in order
Build the body of the getter that returns a FormArray: return this.form.get('skills') as FormArray. Click the elements in order.