FormArray ,FormGroup,FormControl in Angular.
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 .