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>