Angular Reactive Forms: FormArray - Introduction and Implementation

FormArray

Introduction

When we need to work with an array of objects in the form, we can use FormArray. With FormArray we can manage the collection of AbstractControls which can be FormGroup, FormControl, or be it another FormArray. FormArray handles all these as a FormGroup but in an array. 

Implementing A FormArray

Suppose we have a requirement where the user has to add or remove items from a list, we can use FormArray in those scenarios. The first parameter of the constructor of the FormArray class expects an array of AbstractControls. It basically tracks the value of an array of FormGroup, FormControl, or be it another FormArray. 

Example: We will go to our component.ts file and declare a FormArray which serves as a container for all the recipes items in our example. 

import {FormControl, FormGroup, FormArray } from '@angular/forms';
import { Component } from '@angular/core';
@Component({
  selector: 'form-array-form',
  templateUrl: "./form-array-form.component.html",
})
export class FormArrayFormComponent {
    form = new FormGroup({
      recipes: new FormArray([])
    });
}

Now we will go to our component.html file and we will add an input field. This input element is used to add recipes and we will handle this using the key up event. Whenever we write some recipe names in this input field and presses enter, we are going to call the addRecipe() method. We will pass the reference of this input field as a parameter to the addRecipe(). We will also implement the removeRecipe method() here to remove the recipe on clicking the respective recipe name.
<form>
  <input (keyup.enter)="addRecipe(recipe)" class="form-control" #recipe>
</form>

Now we will go to our component.ts file and implement this method. 
import {FormControl, FormGroup, FormArray } from '@angular/forms';
import { Component } from '@angular/core';
@Component({
  selector: 'form-array-form',
  templateUrl: "./form-array-form.component.html",
})

export class FormArrayFormComponent {
    form = new FormGroup({
      recipes: new FormArray([])
    });

  addRecipe(recipe: HTMLInputElement){
   this.recipes.push(new FormControl(recipe.value));
   this.recipes.removeAt(index);
  }
 
  removeRecipe(recipe: FormControl){
   let index = this.recipes.indexOf(recipe);
   
  }
   
   get recipes() {
    return this.form.get('recipes') as FormArray;
    }
}
  
Now we will go to our component.html file and we will implement a list and use
recipes.controls property with *ngFor directive to display the list of recipes. In this way, we can iterate over all the form control objects inside this array. 

<form>
  <input (keyup.enter)="addRecipe(recipe)" class="form-control" #recipe>
  <ul>
    <li *ngFor="let recipe of recipes.controls" (click)="removeRecipe(recipe)">
      {{ recipe.value }}
    </li>
  </ul>
</form>

Comments