FormArray ,FormGroup,FormControl in Angular.

chitaranjan biswal
3 min readMar 27, 2023

FormArray

A FormArray is a type of FormControl that represents an array of form controls. It is used to create forms that allow users to enter multiple sets of data, such as a list of items, or a set of item.

FormGroup

A FormGroup is a collection of FormControls that are organized into a single object. It is used to create forms that collect related data, such as user profile information, or billing and shipping addresses. A FormGroup can contain any number of FormControls or other FormGroups.

FormControl

A FormControl is a single form control element, such as an input, select, or textarea. It is used to create forms that collect a single piece of data, such as a user’s name, email address, or password.

Let’s understand with a simple example :

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

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
form: FormGroup;

constructor(private fb: FormBuilder) {
this.recipeForm = this.fb.group({
chef_name: new FormControl("", [Validators.required]),
location: new FormControl("", [Validators.required]),
reciepe: this.fb.array([
this.fb.group({
reciepe_name: ['', Validators.required],
ingredient: ['', Validators.required],
cooking_time: ['', Validators.required],
}),
]),
});
}

get itemControls(): any {
return this.recipeForm.get('reciepe') as FormArray;
}
}

Above code is for creating a form where one chef can add any number of recipe with help of formArray.

Add multiple item dynamically

Look closely the codes of addItem() function.

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

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
recipeForm!: FormGroup;

constructor(private fb: FormBuilder) {
this.recipeForm = this.fb.group({
chef_name: new FormControl("", [Validators.required]),
location: new FormControl("", [Validators.required]),
reciepe: this.fb.array([
this.fb.group({
reciepe_name: ['', Validators.required],
ingredient: ['', Validators.required],
cooking_time: ['', Validators.required],
}),
]),
});
}


get itemControls(): any {
return this.recipeForm.get('reciepe') as FormArray;
}

addItem() {
const items = this.recipeForm.get('reciepe') as FormArray;
if (!items.invalid) {
items.push(
this.fb.group({
reciepe_name: ['', Validators.required],
ingredient: ['', Validators.required],
cooking_time: ['', Validators.required],
})
);
}
}

}

Remove item from fromArray dynamically

We are going to add another function called removeItem() to remove an item from fromArray.

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

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
recipeForm!: FormGroup;

constructor(private fb: FormBuilder) {
this.recipeForm = this.fb.group({
chef_name: new FormControl("", [Validators.required]),
location: new FormControl("", [Validators.required]),
reciepe: this.fb.array([
this.fb.group({
reciepe_name: ['', Validators.required],
ingredient: ['', Validators.required],
cooking_time: ['', Validators.required],
}),
]),
});
}

get itemControls(): any {
return this.recipeForm.get('reciepe') as FormArray;
}

addItem() {
const items = this.recipeForm.get('reciepe') as FormArray;
if (!items.invalid) {
items.push(
this.fb.group({
reciepe_name: ['', Validators.required],
ingredient: ['', Validators.required],
cooking_time: ['', Validators.required],
})
);
}
}

removeItem(index: any) {
const items = this.recipeForm.get('reciepe') as FormArray;
items.removeAt(index);
}

}

Here have a look at complete codes
app.component.html

<form [formGroup]="recipeForm" class="form-container">
<h2 class="add-header">Add Recipe Form</h2>
<div class="input-container">
<label>Chef Name</label>
<input formControlName="chef_name">
</div>
<div class="input-container">
<label>Location</label>
<input formControlName="location">
</div>
<div class="recipe-header">
<h2 class="add-header">Add recipe</h2> <button class="add-btn" (click)=addItem()>Add</button>
</div>
<div formArrayName="reciepe">
<div *ngFor="let User of itemControls.controls; let i=index">
<div [formGroupName]="i" class="recipe-container">
<div class="sub_input-container">
<label>Recipe Name</label>
<input formControlName="reciepe_name">
</div>
<div class="sub_input-container">
<label>Ingredient</label>
<input formControlName="ingredient">
</div>
<div class="sub_input-container">
<label>Cooking Time</label>
<input formControlName="cooking_time">
</div>
<div class="sub_inputbtn-container">
<button class="remove-btn" (click)=removeItem(i)>remove</button>
</div>
</div>
<hr>
</div>
</div>
<button (click)="submitForm()" class="submit-btn">SUBMIT</button>
</form>

app.component.ts

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

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
recipeForm!: FormGroup;

constructor(private fb: FormBuilder) {
this.recipeForm = this.fb.group({
chef_name: new FormControl("", [Validators.required]),
location: new FormControl("", [Validators.required]),
reciepe: this.fb.array([
this.fb.group({
reciepe_name: ['', Validators.required],
ingredient: ['', Validators.required],
cooking_time: ['', Validators.required],
}),
]),
});
}


get itemControls(): any {
return this.recipeForm.get('reciepe') as FormArray;
}

addItem() {
const items = this.recipeForm.get('reciepe') as FormArray;
if (!items.invalid) {
items.push(
this.fb.group({
reciepe_name: ['', Validators.required],
ingredient: ['', Validators.required],
cooking_time: ['', Validators.required],
})
);
}
}

submitForm() {
console.log(this.recipeForm.value);
}

removeItem(index: any) {
const items = this.recipeForm.get('reciepe') as FormArray;
items.removeAt(index);
}
}

Find the complete code in git here with some added css .

--

--