In Angular, there are several types of control bindings that can be used in reactive forms. These bindings allow you to connect form controls to data sources and apply validation rules.
In this article, we'll look at different bindings available in Angular.
FormGroup
This binding connects a group of form controls to a data model. It creates a nested form structure, where the form controls are grouped together based on their functional relationship.
FormControl
This binding connects a single form control to a data model. It is used to create a single control instance for a form field.
FormArray
This binding connects an array of form controls to a data model. It creates dynamic forms where a user can add or remove form fields.
formControlName
This binding connects a single form control to a data model. It is used in template-driven forms to bind a form control to a data source.
formGroupName
This binding is used to group form controls under a common data model. It is used in template-driven forms to group related form controls.
Prerequisites
Before we begin, you should have a basic understanding of Angular and Reactive Forms. If you're unfamiliar with these topics, you can check out the official Angular documentation at the portal.
I have used the below tools to prepare this tutorial.
- Angular CLI - 15.1.6
- Node: 18.14.0
- NPM – 9.3.1
- Visual Studio Code
Without any delay, let us jump into the coding part.
The source code can be downloaded from GitHub
Create a Strongly Typed Reactive Form
Let's start by creating a new Angular application using the Angular CLI. Open a terminal window in Visual Studio Code and enter the following command:
ng new ReactiveControlBindings
Next, we will create a new component to host our typed reactive form. In the terminal window, enter the following command:
Cd reactivecontrolbindings
Ng generate component contactform
This will create a new " contact-form " component in the src/app directory. Open the component file at src/app/typed-form/contact-form.component.ts and add the following code:
import { Component, OnInit } from '@angular/core';
import { FormArray, FormBuilder, FormControl, FormGroup } from '@angular/forms';
@Component({
selector: 'app-contact-form',
templateUrl: './contact-form.component.html',
styleUrls: ['./contact-form.component.scss']
})
export class ContactFormComponent implements OnInit {
fm = this.fb.group < FormModel > ({
title: this.fb.control('Personal Details'),
name: this.fb.group({
firstName: this.fb.control("PRTeck"),
lastName: this.fb.control("Talks")
}),
hobby: this.fb.array([
this.fb.control('Swimming'),
this.fb.control('Shuttle')
])
});
ngOnInit(): void {}
constructor(private fb: FormBuilder) {}
}
//Model
interface FormModel {
title: FormControl < string | null > ;
name: FormGroup < {
firstName: FormControl < string | null > ;
lastName: FormControl < string | null > ;
} > ;
hobby: FormArray < FormControl < string | null >> ;
}
Binding the Typed Reactive Form to the Template
Now that we have our typed reactive form object, we must bind it to our template. Open the src/app/contact-form/contact-form.component.html file and add the following code:
<form [formGroup]="fm">
<label>Tile
<input formControlName="title"/>
</label>
<label formGroupName="name">
FirstName
<!-- formControlName-->
<input formControlName="firstName" />
</label>
<label>
Last name
<!-- formcontrol -->
<input [formControl]="fm.controls.name.controls.lastName" />
</label>
<label>
hobby
<!--Form Array -->
<ul *ngFor="let cc of fm.controls.hobby.controls">
<li><input [formControl]="cc"/></li>
</ul>
</label>
</form>
Let me explain each part of this code:
- [formGroup]="fm": This directive sets the form group for the entire form. fm is a property of the component's class that holds the form group.
- <label>Tile: This HTML label element provides a caption for the form field that follows it.
- <input formControlName="title"/>: This is an HTML input element that is associated with the form control named "title". The formControlName directive binds the input element to the corresponding form control defined in the form group.
- <label formGroupName="name">: This is an HTML label element that defines a nested form group named "name". This is useful when we have a group of related form controls.
- <input formControlName="firstName" />: This is an HTML input element that is associated with the form control named "firstName" in the nested form group "name". The formControlName directive binds the input element to the corresponding form control defined in the nested form group.
- <input [formControl]="fm.controls.name.controls.lastName" />: This is an HTML input element that is associated with the form control named "lastName" in the nested form group "name". Instead of using the formControlName directive, we use the [formControl] binding syntax to bind the input element to the corresponding form control defined in the nested form group.
- <ul *ngFor="let cc of fm.controls.hobby.controls">: This HTML unordered list element defines a form array named "hobby". The *ngFor directive is used to loop over the controls in the form array and create an input element for each control.
- <li><input [formControl]="cc"/></li>: This is an HTML list item element that contains an input element. The [formControl] binding syntax is used to bind the input element to the current control in the loop. This creates an input element for each control in the form array.
- </form>: This is the closing tag for the form element.
Let us go ahead and execute the URL http://locahost:4200
In conclusion, the code defines a simple Angular component that creates a reactive form using FormBuilder. The form has three form controls: title, name, and hobby. The name control is defined as a nested form group with two form controls: firstName and lastName. The hobby control is defined as a form array with two form controls. The code also binds the form controls to HTML form elements using the formControlName and [formControl] binding syntax. This code demonstrates how to create a basic strongly typed reactive form in an Angular application.