Adding Elements Dynamically in Angular is a very hot and interesting topic. Angular gives us two nice ways to handle form data Reactive Form & Template Driven Form. In this blog, I am going to share how can we dynamically add form field controls in Reactive form.
Prerequesties:
Knowledge of Angular Reactive form, JavaScript.
What is an Angular FormArray?
In Angular Reactive Forms, every form has a form model defined programmatically using the FormControl
and FormGroup
APIs, or alternatively using the more concise FormBuilder
API, which we will be using throughout this guide.
Imagine a dynamic form where form controls are added or removed to the form by the user, depending on its interaction with the UI.
An example would be a form that is fully dynamically built according to data coming from the backend!
Another more common example of a dynamic form would be an in-place editable form, where the user can add or remove lines containing multiple editable form controls:
In this dynamic form, the user can add or remove new controls to the form by using the Add and remove buttons.
Each time that the user clicks on the Add New Role button, a new role field will be added to the form containing new form controls.
The FormArray API
These are the most commonly used methods available in the FormArray
API:
- controls: This is an array containing all the controls that are part of the array
- length: This is the total length of the array
- at(index): Returns the form control at a given array position
- push(control): Adds a new control to the end of the array
- removeAt(index): Removes a control at a given position of the array
- getRawValue(): Gets the values of all form controls, via the
control.value
property of each control
Creating Angular Dynamic Form:
First of all, we need to create a reactive form so I am going to import FormBuild API in my component.
constructor(private fb: FormBuilder) {}
Now I will create a form with 3 fields ( email, password & roles )
form = this.fb.group({
email: [
'',
{
validators: [Validators.required, Validators.email],
},
],
password: ['', [Validators.required, Validators.minLength(8)]],
roles: this.fb.array([]),
});
In this form, there are three fields Email, Password, and roles with angular pre-built validations. roles field is a form array so we will add or remove controls from this FormControl.
So in the next step, we will create a getter function that returns the roles field as a form Array.
get rolesFieldAsFormArray(): any {
return this.form.get('roles') as FormArray;
}
We will use this getter method in our HTML file to dynamically display all added new fields and also to add and remove controls.
Now Let’s create a method that will return a form that we want to add dynamically in our roles field.
role(): any {
return this.fb.group({
role: this.fb.control(''),
});
}
In this method, I am returning a form group with role control.
Dynamically adding controls to a FormArray
Now create a method that will add new controls in our roles form-control.
addControl(): void {
this.rolesFieldAsFormArray.push(this.role());
}
In this method, I used my getter method to add new controls.
Dynamically removing controls from a FormArray
Now create a method that will remove controls from our roles form field.
remove(i: number): void {
this.rolesFieldAsFormArray.removeAt(i);
}
In this method, we will get the control index from the HTML part and will remove the control.
Now create a method that will console our form value.
formValue(): void {
console.log(this.form.value);
}
Let’s move to the HTML part
<form [formGroup]="form">
<div class="input-field">
<input matInput type="email" name="email"
placeholder="Email" formControlName="email">
</div>
<div class="input-field">
<input matInput type="password"
placeholder="Password" formControlName="password">
</div>
<div *ngFor="let control of rolesFieldAsFormArray.controls ;let i = index;" formArrayName='roles' >
<div [formGroupName]="i" >
<div class="input-field" >
<input matInput type="text"
placeholder="Role" formControlName="role" >
</div>
<button class="button" type="button" (click)="remove(i)" >Remove</button>
</div>
</div>
<button class="button" (click)="addControl()" > Add New Role</button>
<button class="button" type="submit" (click)="formValue()" [disabled]="form.invalid">
Login
</button>
</form>
So now, our form is ready
Now I will run my code and add and remove some controls.
Below I added a video.
Wrapping up the text:
So in this blog, we learn how can we add and remove controls from our form Array. Sometimes we need to create a dynamic form that will add different types of forms in our form so by this approach we can easily add multiple forms.
As we can see, the FormArray
constructor or FormBuilder API is very powerful and comes in especially handy in situations where we want to build our form model in a more dynamic way.
.