Validations In Reactive Forms In Angular
In this article, We will learn how angular reactive forms validation works. Validation is one of the most common tasks undertaken when creating a form. We will demonstrate how to create Reactive Forms and use built-in validators. In the following article, We will learn how to use Reactive Forms to develop custom validators.
In the Template-driven Forms article, we looked at how validation works. The majority of the principles covered in that tutorial apply here as well.
Validators in Reactive Forms
What is a Validator
A Validator is a function that checks and returns a list of errors for a FormControl, FormGroup, or FormArray instance. Validation has passed if the Validator returns a null value.
How to add a Validator to Reactive Forms
The validators are set as the second and third arguments in the component class's FormControl, FormGroup, or FormArray. A collection of sync validators is the second argument, and a collection of async validators is the third.
Validation is performed and results are returned promptly by sync validators. If no errors are discovered, they either return null or a list of errors.
Validators that are asynchronous: return a Promise or an Observable. If no errors are discovered, they either return null or a list of errors.
Built-in Validators
The Angular ReactiveForms Module comes with a number of built-in validators. They are required, including minlength, maxlength, and pattern, among other things.
Reactive Forms Validation Example
In the previous tutorial, W learned how to develop Angular Reactive Forms. To that example, we'll now add some of the built-in validators.
Model
The contactForm model from the last instruction is shown here.
- contactForm = new FormGroup({
- firstname: new FormControl(''),
- lastname: new FormControl(''),
- email:new FormControl(''),
- gender: new FormControl(''),
- isMarried: new FormControl(''),
- country: new FormControl(''),
- address:new FormGroup({
- city: new FormControl(''),
- street: new FormControl(''),
- pincode:new FormControl('')
- })
- })
Disabling the Browser validation
- <form contactform="" formgroup="" ngsubmit="" novalidate="" onsubmit="">
Adding in Built-in Validators
Required Validator
- firstname: new FormControl('',[Validators.required]),
Minlength Validator
- firstname: new FormControl('',[Validators.required,Validators.minLength(10)]),
Maxlength Validator
- lastname: new FormControl('',[Validators.maxLength(15)]),
Pattern Validator
- lastname: new FormControl('',[Validators.maxLength(15), Validators.pattern("^[a-zA-Z]+$")]),
Email Validator
- email:new FormControl('',[Validators.email,Validators.required]),
Our final contactForm will look like this after we've added all of the validators.
- contactForm = new FormGroup({
- firstname: new FormControl('',[Validators.required,Validators.minLength(10)]),
- lastname: new FormControl('',[Validators.required, Validators.maxLength(15), Validators.pattern("^[a-zA-Z]+$")]),
- email:new FormControl('',[Validators.email,Validators.required]),
- gender: new FormControl('',[Validators.required]),
- isMarried: new FormControl('',[Validators.required]),
- country: new FormControl('',[Validators.required]),
- address:new FormGroup({
- city: new FormControl('',[Validators.required]),
- street: new FormControl('',[Validators.required]),
- pincode:new FormControl('',[Validators.required])
- })
- })
Disable Submit button
- <button contactform.valid="" disabled="" type="submit">Submit</button>
Displaying the Validation/Error messages
- <div ngif="!contactForm.controls.firstname?.valid && (contactForm.controls.firstname?.dirty
- ||contactForm.controls.firstname?.touched)">
- First Name is not valid
- </div>
Another option is to define a getter function in the component class for each FormControl instance.
- get firstname() {
- return this.contactForm.get('firstname');
- }
and then use it as follows in the template
- <div ngif="!firstname.valid && (firstname.dirty ||firstname.touched)">
- First Name is not valid
- </div>
Dirty & touched
Error message
- <div ngif="!firstname?.valid && (firstname?.dirty ||firstname?.touched)">
- <div firstname.errors.required="" hidden="">
- First Name is required
- </div>
- <div firstname.errors.minlength="" hidden="">
- Min Length is 10
- </div>
- </div>
The following code is complete code of the app.component.ts file
- import { Component, ViewChild, ElementRef } from '@angular/core';
- import { FormGroup, FormControl, Validators } from '@angular/forms'
- @Component({
- selector: 'app-root',
- templateUrl: './app.component.html',
- styleUrls: ['./app.component.css']
- })
- export class AppComponent {
- title = 'Angular Reactive forms';
- contactForm = new FormGroup({
- firstname: new FormControl('',[Validators.required,Validators.minLength(10)]),
- lastname: new FormControl('',[Validators.required, Validators.maxLength(15), Validators.pattern("^[a-zA-Z]+$")]),
- email:new FormControl('',[Validators.email,Validators.required]),
- gender: new FormControl('',[Validators.required]),
- isMarried: new FormControl('',[Validators.required]),
- country: new FormControl('',[Validators.required]),
- address:new FormGroup({
- city: new FormControl('',[Validators.required]),
- street: new FormControl('',[Validators.required]),
- pincode:new FormControl('',[Validators.required])
- })
- })
- get firstname() {
- return this.contactForm.get('firstname');
- }
- get lastname() {
- return this.contactForm.get('lastname');
- }
- get email() {
- return this.contactForm.get('email');
- }
- get gender() {
- return this.contactForm.get('gender');
- }
- get isMarried() {
- return this.contactForm.get('isMarried');
- }
- get country() {
- return this.contactForm.get('country');
- }
- get city() {
- return this.contactForm.get("address").get('city');
- }
- get street() {
- return this.contactForm.get("address").get('street');
- }
- get pincode() {
- return this.contactForm.get("address").get('pincode');
- }
- countryList: country[] = [
- new country("1", "India"),
- new country('2', 'USA'),
- new country('3', 'England')
- ];
- onSubmit() {
- console.log(this.contactForm.value);
- }
- }
- export class contact {
- firstname:string;
- lastname:string;
- gender:string;
- isMarried:boolean;
- country:string;
- address: {
- city:string;
- street:string;
- pincode:string;
- }
- }
- export class country {
- id: string;
- name: string;
- constructor(id: string, name: string) {
- this.id = id;
- this.name = name;
- }
- }
The following code is complete code of the app.component.html file
- <form [formGroup]="contactForm" (ngSubmit)="onSubmit()" novalidate>
- <p>
- <label>First Name </label>
- <input formcontrolname="firstname" id="firstname" name="firstname" type="text" />
- </p>
- <div ngif="!firstname?.valid && (firstname?.dirty ||firstname?.touched)">
- <div firstname.errors.required="" hidden="">
- First Name is required
- </div>
- <div firstname.errors.minlength="" hidden="">
- Min Length is 10
- </div>
- </div>
- <p>
- <label>Last Name </label>
- <input formcontrolname="lastname" id="lastname" name="lastname" type="text" />
- </p>
- <div ngif="!lastname.valid && (lastname.dirty ||lastname.touched)">
- <div hidden="" lastname.errors.pattern="">
- Only characters are allowed
- </div>
- <div hidden="" lastname.errors.maxlength="">
- Max length allowed is {{lastname.errors.maxlength?.requiredLength}}
- </div>
- <div hidden="" lastname.errors.required="">
- Last Name is required
- </div>
- </div>
- <p>
- <label>Email </label>
- <input formcontrolname="email" id="email" name="email" type="text" />
- </p>
- <div ngif="!email.valid && (email.dirty ||email.touched)">
- <div email.errors.required="" hidden="">
- email is required
- </div>
- <div email.errors.email="" hidden="">
- invalid email id
- </div>
- </div>
- <p>
- <label>Geneder </label>
- <input formcontrolname="gender" id="gender" name="gender" type="radio" value="male" /> Male
- <input formcontrolname="gender" id="gender" name="gender" type="radio" value="female" /> Female
- </p>
- <div ngif="!gender.valid && (gender.dirty ||gender.touched)">
- <div gender.errors.required="" hidden="">
- gender is required
- </div>
- </div>
- <p>
- <label>Married </label>
- <input formcontrolname="isMarried" id="isMarried" name="isMarried" type="checkbox" />
- </p>
- <div ngif="!isMarried.valid && (isMarried.dirty ||isMarried.touched)">
- <div hidden="" ismarried.errors.required="">
- isMarried is required
- </div>
- </div>
- <p>
- <label>country </label>
- <select formcontrolname="country" id="country" name="country">
- <option c.id="" ngfor="let c of countryList" ngvalue="">
- {{c.name}}
- </option>
- </select>
- </p>
- <div ngif="!country.valid && (country.dirty ||country.touched)">
- <div country.errors.required="" hidden="">
- country is required
- </div>
- </div>
- <div formgroupname="address">
- <div class="form-group">
- <label>City</label>
- <input class="form-control" formcontrolname="city" name="city" type="text" />
- </div>
- <div ngif="!city.valid && (city.dirty ||city.touched)">
- <div city.errors.required="" hidden="">
- city is required
- </div>
- </div>
- <div class="form-group">
- <label>Street</label>
- <input class="form-control" formcontrolname="street" name="street" type="text" />
- </div>
- <div ngif="!street.valid && (street.dirty ||street.touched)">
- <div hidden="" street.errors.required="">
- street is required
- </div>
- </div>
- <div class="form-group">
- <label>Pin Code</label>
- <input class="form-control" formcontrolname="pincode" name="pincode" type="text" />
- </div>
- <div ngif="!pincode.valid && (pincode.dirty ||pincode.touched)">
- <div hidden="" pincode.errors.required="">
- pincode is required
- </div>
- </div>
- </div>
- <p>{{contactForm.valid}} </p>
- <p>
- <button contactform.valid="" disabled="" type="submit">Submit</button>
- </p>
- </form>