FormArray In Angular
In this article, We will learn how to make a simple FormArray with Example application. The FormArray is demonstrated in the Angular FormArray sample. The FormArray allows us to dynamically add controls to reactive forms. We will use the task of dynamically adding and removing abilities from an employee form as an example.
What is FormArray
In Angular, the FormArray is a mechanism to handle a collection of Form Controls. A FormGroup, FormControl, or another FormArray can be used as controls.
In Angular forms, there are two ways to organize Form Controls. One employs FormGroup, whereas the other employs FormArray. The difference is in how they go about doing it. Controls in a FormGroup become a property of the FormGroup. A key-value pair is used to represent each control. The controls in FormArray become part of an array.
It's easy to dynamically add controls because it's implemented as an Array.
FormArray Example
Let's make a basic app that allows us to dynamically add a person's new talent.
Import FormArray
You must first import FormArray from the Angular Forms Module in order to use it.
import { FormGroup, FormControl,FormArray, FormBuilder } from '@angular/forms'
Build a Form Model
skillsForm: FormGroup; constructor(private fb:FormBuilder) { this.skillsForm = this.fb.group({ name: '', skills: this.fb.array([]) , }); }
Then there's a skills getter method, which returns the skills Form. from the skillsForm array
get skills() : FormArray { return this.skillsForm.get("skills") as FormArray }
The skill FormGroup
newSkill(): FormGroup { return this.fb.group({ skill: '', exp: '', }) }
Dynamically adding skill
addSkills() { this.skills.push(this.newSkill()); }
Dynamically Removing Skill
removeSkill(i:number) { this.skills.removeAt(i); }
Submit
onSubmit() { console.log(this.skillsForm.value); }
Template
<form [formGroup]="skillsForm" (ngSubmit)="onSubmit()"> <p> <label for="name">Name </label> <input type="text" id="name" name="name" formControlName="name"> </p> <p> <button type="submit">Submit</button> </p> </form>
Binding FormArray to Template
<div formArrayName="skills"> </div>
Use ngFor to loop through each element of the skills FormArray inside the div. let i=index stores the array's index value in the template local variable i. We'll use it to take the element out of the talents array.
<div formArrayName="skills"> <div *ngFor="let skill of skills().controls; let i=index"> </div> </div>
<div formArrayName="skills"> <div *ngFor="let skill of skills().controls; let i=index"> <div [formGroupName]="i"> </div> </div> </div>
Finally, we use the formControlName directive to add the controls.
Skills: <div formArrayName="skills"> <div *ngFor="let skill of skills().controls; let i=index"> <div [formGroupName]="i"> {{i}} skill name : <input type="text" formControlName="skill"> exp: <input type="text" formControlName="exp"> <button (click)="removeSkill(i)">Remove</button> </div> </div> </div>
RemoveSkill should also be given the index i.
<button (click)="removeSkill(i)">Remove</button>
Finally, to add new skills, use the addSkills function.
<p> <button type="button" (click)="addSkills()">Add</button> </p>
import { Component, ViewChild, ElementRef } from '@angular/core'; import { FormGroup, FormControl,FormArray, FormBuilder } from '@angular/forms' @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { title = 'FormArray Example in Angular Reactive forms'; skillsForm: FormGroup; constructor(private fb:FormBuilder) { this.skillsForm = this.fb.group({ name: '', skills: this.fb.array([]) , }); } get skills() : FormArray { return this.skillsForm.get("skills") as FormArray } newSkill(): FormGroup { return this.fb.group({ skill: '', exp: '', }) } addSkills() { this.skills.push(this.newSkill()); } removeSkill(i:number) { this.skills.removeAt(i); } onSubmit() { console.log(this.skillsForm.value); } } export class country { id: string; name: string; constructor(id: string, name: string) { this.id = id; this.name = name; } }
The following code is complete code of the app.component.html
<form [formGroup]="skillsForm" (ngSubmit)="onSubmit()"> <p> <label for="name">Name </label> <input type="text" id="name" name="name" formControlName="name"> </p> Skills: <div formArrayName="skills"> <div *ngFor="let skill of skills().controls; let i=index"> <div [formGroupName]="i"> {{i}} skill name : <input type="text" formControlName="skill"> exp: <input type="text" formControlName="exp"> <button (click)="removeSkill(i)">Remove</button> </div> </div> </div> <p> <button type="submit">Submit</button> </p> </form> <p> <button type="button" (click)="addSkills()">Add</button> </p> {{this.skillsForm.value | json}}