Here, in this blog we will work with reactive angular forms. So, with consideration that you have basic knowledge of Angular, Typescript, HTML and CSS you can start with your first angular reactive form.
In this blog, we will cover below points:
- What are Template Forms
- What are Reactive Forms
- Setup in reactive forms
- FormControl
- FormGroup
- FormBuilder
- Adding Validation
As angular provides two types of forms:
- Template Driven Forms
- Reactive Forms
What are Template Forms?
By definition, template driven forms are forms where we write logic, validations, controls etc, in the template part of the code (html code). The template is responsible for setting up the form, the validation, control, group etc. Template driven forms are suitable for simple scenarios, uses two way data binding using the [(NgModel)] syntax, easier to use though unit testing might be a challenge.
What are Reactive Forms?
Reactive forms provide direct, explicit access to the underlying forms object model. Compared to template-driven forms, they are more robust: they’re more scalable, reusable, and testable. If forms are a key part of your application, or you’re already using reactive patterns for building your application, use reactive forms.
The major difference between these two approaches of creating forms? In reactive forms you do not use directives such as ngModel, required, etc. You create all controls and their validations in the component class. Reactive forms are easy to test and maintain, so in this post we will learn to create a basic Reactive Form, using FormControl, FormGroup, FormBuilder class, and adding validations.
After discussing both the types of forms and their differences we will continue with reactive forms in angular.
Setup in reactive forms
To start with angular reactive forms, first we have to add ReactiveFormsModule in the App Module. Also, we need to import different required angular reactive forms classes as FormGroup, FormControl, FormArray in the component classes. These classes are used to develop the reactive form.
changes in app Module
import { AppComponent } from './app.component';
import { ReactiveFormsModule } from '@angular/forms';
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
ReactiveFormsModule
],
bootstrap: [AppComponent]
})
export class AppModule { }
.ts component
import { Component } from '@angular/core';
import { FormGroup, FormControl, FormArray } from '@angular/forms';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'First Reactive Form';
}
Now, here different classes are imported in component, we will understand each classes in continue of this blog.
FormControl
FormControl class corresponds to one individual form control with its value and validity. For creating a reactive form, we have to create an object of the FormControl class. The FormControl constructor is parameterised. Constructor takes three parameters as listed below in sequence:
- First is non- optional: Initial value, value can be null provided
- Second is optional : Synchronous validators array
- Third is also optional: Asynchronous validators array
Next, we can create a FormControl object in component class as shown below:
export class AppComponent {
name = new FormControl('');
}
Here in above example we are passing only one parameter because first is compulsory and another two are optional. We will discuss validator parameter later in this blog. Also in the view, proceed as follow with your formControl:
<input [formControl]='name'
type="text"
placeholder="Enter Your Name" />
Here in view we are using property binding to bind the formControl name to the input element on the view.
FormGroup
Now, by understanding with name FormGroup is a group of multiple FormControls. You can encapsulate various different FormControls inside the FormGroup.
Next, we can create FormGroup class as shown below:
learningForm = new FormGroup({
Name: new FormControl(' '),
Age: new FormControl('0')
})
In the above code we have created a new form as learningForm, which is a FormGroup encapsulating two different FormControls for name and age.
Now, let’s see the view part to understand the use of FormGroup.
<form [formGroup]='learningForm' novalidate class="form">
<input formControlName='name'
type="text"
class="form-control"
placeholder="Enter Name" />
<input formControlName='age'
type="number"
class="form-control"
placeholder="Enter Age" />
</form>
So, you can see here we used property binding to bind our FormGroup with the form. Also, there is one directive formControlName used to attach formControl to a particular element on the view.
FormBuilder
Suppose a case where we have to define multiple FormGroups and FormControls for the same form. Then we have to define FormControl for each form element. This will result to a lengthy and complicated programming. FormBuilder is the useful solution for the above mentioned case. FormBuilder is used to simplify the syntax for FormGroup and FormControl. For using FormBuilder, first import the FormBuilder from @angular/forms. Then inject it to the component.
constructor(private fb : FormBuilder){}
As FormBuilder is injected, now generate the form contents. Let’s refactor our learningForm to simplify the syntax using FormBuilder.
this.learningForm = this.fb.group({
name: [null]
age: [null]
})
The view template will be the same for both FormBuilder and FormControl classes.
Adding validations
Also, in reactive form we can add different validators in the form. So, in this blog we will learn the basics of validators in angular reactive form. Lets us start by adding a validation to FormControl. First import Validators from @angular/forms. Next, add the validation array as the second parameter of FormControl.
In case of using FormGroup:
this.learningForm = new FormGroup({
name: new FormControl(null, [Validators.required), Validators.maxLength(8)],
age: new FormControl(null, Validators.required)
});
In case of using FormBuilder:
this.learningForm = this.fb.group({
name: [null, [Validators.required, Validators.maxLength(8)]],
age: [null, Validators.required]
})
There are different types of validators we can provide to each form element. Also multiple validators can also be applied on form elements. In the above example, we have provided multiple validators to name elements and one validator to age element. For getting valid form status, users need to satisfy all the required validation.
On the template, you can use the FormGroup get method to find an error in a particular form control and use it for displaying an error message to the user.
<div class="alert alert-danger"
*ngIf="learningForm.get(name).hasError('required') && learningForm.get(name).touched">
Name is Required
</div>
*ngIf="learningForm.get(name).hasError('maxLength') && learningForm.get(name).touched">
Name has maximum 8 characters
</div>
Here, if user touched the name element and leave with null value then error message will be displayed that name is required.
Conclusion:
Creating of basic angular reactive form can be possible with content provided in the blog.
In conclusion , the template with reactive forms will look like the following:
<div class="container">
<br />
<form (ngSubmit)=submitForm()' [formGroup]='learningForm' novalidate class="form">
<input formControlName='name' type="text" class="form-control" placeholder="Enter name" />
<div class="alert alert-danger" *ngIf="!learningForm.get('name').valid && learningForm.get('name').touched">
Name is required and should less than 10 characters
</div>
<input formControlName='age' type="number” class="form-control" placeholder="Enter age" />
<div class="alert alert-danger" *ngIf=" learningForm.get('age').hasError(‘required’) && learningForm.get('age').touched">
Age is required
</div>
<button [disabled]='learningForm.invalid' class="btn btn-default">Submit</button>
</form>
</div>
Putting everything together, the component using FormGroup to create a reactive form will look like this:
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormControl, FormArray, Validators } from '@angular/forms';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
learningForm: FormGroup;
ngOnInit() {
this.learningForm = new FormGroup({
name: new FormControl(null, [Validators.required), Validators.maxLength(8)],
age: new FormControl(null, Validators.required)
});
}
submitForm() {
console.log(this.learningForm.status);
console.log(this.learningForm.value);
}
}
Putting everything together, the component using FormBuilder to create a reactive form will look like this:
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormControl, FormArray, Validators, FormBuilder } from '@angular/forms';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
learningForm: FormGroup;
constructor(private fb: FormBuilder) {}
ngOnInit() {
this.learningForm = this.fb.group({
name: [null, [Validators.required, Validators.maxLength(8)]],
age: [null, Validators.required]
})
}
submitForm() {
console.log(this.learningForm.status);
console.log(this.learningForm.value);
}
}
To learn more about angular reactive forms click here.
For more tech blogs, please visit Knoldus Blogs.