Angular Js

Explain FormArray in Angular

Explain FormArray in Angular

FormArray in Angular

This Article helps you to Understand, FormArray in Angular


A collection of form controls is called a FormArray.
Except for one exception, it is similar to FormGroup. Every FormControl within a FormGroup has a property with the control name as the key. An array of form controls is in FormArray. When we wish to dynamically construct form controls like "input" and "select," we use FormArray.


Lets Add Logic to create New Input field at run time to add new user



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

@Component({
   selector: 'app-form-array',
   templateUrl: 'formarray.component.html'
})
export class FormArrayComponent{
  userForm = new FormGroup({
    users: new FormArray([
      new FormControl('Deepak'),
      new FormControl('Sanjay'),
      new FormControl()
    ])
  });
  get users(): FormArray {
     return this.userForm.get('users') as FormArray;
  }
  addUserField() {
     this.users.push(new FormControl());
  }
  deleteUserField(index: number) {
     this.users.removeAt(index);
  }


  onFormSubmit() {
    console.log(this.users.value); // Gives FormArray data
    console.log(this.userForm.value); // Gives Complete form data

    //Iterate FormArray
    for(let i = 0; i < this.users.length; i++) {
    console.log(this.users.at(i).value);
    }
  }
}



<h3> Using FormControl with FormArray </h3>
<div>
    <form [formGroup]="userForm" (ngSubmit)="onFormSubmit()">

      <div formArrayName="users">
        <div *ngFor="let user of users.controls; index as idx">
          <input [formControlName]="idx" placeholder="Enter User Name">
          <button (click)="deleteUserField(idx)">Delete</button>
        </div>
      </div>

      <button type="submit">Submit</button>
      <button type="button" (click)="addUserField()">Add More User</button>
    </form>
</div>



Lets add Form Module in app.module.ts


import { NgModule } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';

import { AppComponent }  from './app.component';
import { FormArrayComponent }  from './formarray.component';


@NgModule({
  imports: [
    BrowserModule,
  ReactiveFormsModule
  ],
  declarations: [
        AppComponent,
  FormArrayComponent,
  ],
  bootstrap: [
        AppComponent
  ]
})
export class AppModule { }




Example 2: Can Handle a Complex Object in FormArray


import { Component, OnInit } from "@angular/core";
import { ActivatedRoute, Params, Router } from "@angular/router";
import { FormGroup, FormControl, FormArray, Validators } from "@angular/forms";
import { RecipeService } from "../recipe.service";


@Component({
  selector: "app-recipe-edit",
  templateUrl: "./recipe-edit.component.html",
  styleUrls: ["./recipe-edit.component.css"],
})
export class RecipeEditComponent implements OnInit {
  id: number;
  editMode = false;
  recipeForm: FormGroup;

  get controls() {   
    return (<FormArray>this.recipeForm.get("ingredients")).controls;
  }

  constructor(
    private route: ActivatedRoute,
    private recipeService: RecipeService,
    private router: Router
  ) {}

  ngOnInit() {
    this.route.params.subscribe((params: Params) => {
      this.id = +params["id"];
      this.editMode = params["id"] != null;
      this.initForm();
    });
  }

  onSubmit() {
    if (this.editMode) {
      this.recipeService.updateRecipe(this.id, this.recipeForm.value);
    } else {
      this.recipeService.addRecipe(this.recipeForm.value);
    }
    this.onCancel();
  }

  onAddIngredient() {
    (<FormArray>this.recipeForm.get("ingredients")).push(
      new FormGroup({
        name: new FormControl(null, Validators.required),
        amount: new FormControl(null, [
          Validators.required,
          Validators.pattern(/^[1-9]+[0-9]*$/),
        ]),
      })
    );
  }

  onDeleteIngredient(index: number) {
    (<FormArray>this.recipeForm.get("ingredients")).removeAt(index);
  }


  private initForm() {
    //make this blank for add mode
    let recipeName = "";
    let recipeImagePath = "";
    let recipeDescription = "";
    let recipeIngredients = new FormArray([]);
   
    if (this.editMode) {
      const recipe = this.recipeService.getRecipe(this.id);
      recipeName = recipe.name;
      recipeImagePath = recipe.imagePath;
      recipeDescription = recipe.description;

      if (recipe["ingredients"]) {
        for (let ingredient of recipe.ingredients) {
          recipeIngredients.push(
            new FormGroup({
              name: new FormControl(ingredient.name),
              amount: new FormControl(ingredient.amount),
            })
          );
        }
      }
    }

    this.recipeForm = new FormGroup({
      name: new FormControl(recipeName, Validators.required),
      imagePath: new FormControl(recipeImagePath, Validators.required),
      description: new FormControl(recipeDescription, Validators.required),
      ingredients: recipeIngredients,
    });
  }
}



Our Template would be


<div class="row">
  <div class="col-xs-12">
    <form [formGroup]="recipeForm" (ngSubmit)="onSubmit()">
      <div class="row">
        <div class="col-xs-12">
          <button
            type="submit"
            class="btn btn-success"
            [disabled]="!recipeForm.valid"
          >
            Save
          </button>
          <button type="button" class="btn btn-danger" (click)="onCancel()">
            Cancel
          </button>
        </div>
      </div>
      <div class="row">
        <div class="col-xs-12">
          <div class="form-group">
            <label for="name">Name</label>
            <input
              type="text"
              id="name"
              class="form-control"
              formControlName="name"
            />
          </div>
        </div>
      </div>
      <div class="row">
        <div class="col-xs-12">
          <div class="form-group">
            <label for="imagePath">Image URL</label>
            <input
              type="text"
              id="imagePath"
              class="form-control"
              formControlName="imagePath"
              #imagePath
            />
          </div>
        </div>
      </div>
      <div class="row">
        <div class="col-xs-12">
          <img [src]="imagePath.value" alt="" class="img-responsive" />
        </div>
      </div>
      <div class="row">
        <div class="col-xs-12">
          <div class="form-group">
            <label for="description">Description</label>
            <textarea
              type="text"
              id="description"
              class="form-control"
              rows="6"
              formControlName="description"
            ></textarea>
          </div>
        </div>
      </div>


      <div class="row">
        <div class="col-xs-12" formArrayName="ingredients">
          <div
            class="row"
            *ngFor="let ingredientCtrl of controls; let i = index"
            [formGroupName]="i"
            style="margin-top: 10px;"
          >
            <div class="col-xs-8">
              <input type="text" class="form-control" formControlName="name" />
            </div>
            <div class="col-xs-2">
              <input
                type="number"
                class="form-control"
                formControlName="amount"
              />
            </div>
            <div class="col-xs-2">
              <button
                type="button"
                class="btn btn-danger"
                (click)="onDeleteIngredient(i)"
              >
                X
              </button>
            </div>
          </div>
          <hr />
          <div class="row">
            <div class="col-xs-12">
              <button
                type="button"
                class="btn btn-success"
                (click)="onAddIngredient()"
              >
                Add Ingredient
              </button>
            </div>
          </div>
        </div>
      </div>
    </form>
  </div>
</div>






Related Post

About Us

Community of IT Professionals

A Complete IT knowledgebase for any kind of Software Language, Development, Programming, Coding, Designing, Networking, Hardware and Digital Marketing.

Instagram