Angular Reactive Forms Validation

By | | Updated : 2021-04-11 | Viewed : 143 times

Angular Reactive Forms Validation

In UI applications, using forms is the basic necessity. When we use the forms, validation is a basic requirement. So angular also provides different ways to validate the forms. Here we will learn how to apply validations on angular reactive forms.

Angular Reactive Forms Validation Example

In previous article, we can learn what is reactive forms and their usage with a good example. So To start the Angular Reactive Forms Validation Example, we are required to create a separate control class and HTML. Please have a look at this.

Here we are going to apply the validation for the billing details web page. We will write the first Html template code. Please look at this.

billing-details.component.html
<div class="container">
    <div class="row">
      <form [formGroup]="userForm">
  
        <h4 class="mb-3">Billing address</h4>
  
        <div class="mb-4">
          <label for="firstName">First name</label>
          <input class="form-control" formControlName="firstName" type="text">
        </div>
        <div *ngIf="firstName.invalid && (firstName.dirty || firstName.touched)" class="alert alert-danger">
          <div *ngIf="firstName.errors.required">
            FirstName is required.
          </div>
          <div *ngIf="firstName.errors.minlength">
            FirstName must be at least 4 characters long.
          </div>
  
        </div>
  
        <div class="mb-3">
          <label for="lastName">Last name</label>
          <input class="form-control" formControlName="lastName" type="text">
        </div>
        <div *ngIf="lastName.invalid && (lastName.dirty || lastName.touched)" class="alert alert-danger">
          <div *ngIf="lastName.errors.required">
            LastName is required.
          </div>
          <div *ngIf="lastName.errors.minlength">
            LastName must be at least 4 characters long.
          </div>
  
        </div>
        <div class="mb-3">
          <label for="userName">Username</label>
          <div class="input-group">
            <div class="input-group-prepend">
              <span class="input-group-text">@</span>
            </div>
            <input class="form-control" formControlName="userName" type="text">
          </div>
  
        </div>
        <div *ngIf="userName.invalid && (userName.dirty || userName.touched)" class="alert alert-danger">
          <div *ngIf="userName.errors.required">
            UserName is required.
          </div>
          <div *ngIf="userName.errors.minlength">
            UserName must be at least 4 characters long.
          </div>
  
        </div>
        <div class="mb-3">
          <label for="email">Email <span class="text-muted">(Optional)</span></label>
          <input class="form-control" formControlName="email" type="email">
        </div>
        <div *ngIf="email.invalid && (email.dirty || email.touched)" class="alert alert-danger">
          <div *ngIf="email.errors.required">
            Email is required.
          </div>
          <div *ngIf="email.errors.validateEmail">
            Email must be valid.
          </div>
        </div>
        
        <div class="mb-3">
          <label for="address1">Address 1</label>
          <input class="form-control" formControlName="address1" type="text">
        </div>
        <div *ngIf="address1.invalid && (address1.dirty || address1.touched)" class="alert alert-danger">
          <div *ngIf="address1.errors.required">
            Address1 is required.
          </div>
        </div>
        <div class="mb-3">
          <label for="address2">Address 2</label>
          <input class="form-control" formControlName="address2" type="text">
  
        </div>
      </form>
      <div class="d-flex w-100 pt-4 ">
        <button (click)="logFormValue()" class="btn btn-primary">Log Billing address</button>
      </div>
      <div class="d-flex w-50 pt-4 ">
        <p>
          Form Value: {{ userForm.value | json }}
        </p>
      </div>
    </div>
  </div>
billing-details.component.ts
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms';
import { User } from '../model/user';
import { EmailValidator } from '../validators/email-validator';

@Component({
  selector: 'app-billing-details',
  templateUrl: './billing-details.component.html',
  styleUrls: ['./billing-details.component.css']
})
export class BillingDetailsComponent implements OnInit {

  submitted = false;
  userForm: FormGroup;

  user = {
    firstName: 'firstName',
    lastName: 'lastName',
    userName: 'userName',
    email: 'you@example.com',
    address1: 'Addres line1',
    address2: 'Addres line2'
  };
  constructor(private formBuilder: FormBuilder) { }
  ngOnInit() {
    this.userForm = new FormGroup({
      firstName: new FormControl(this.user.firstName, [
        Validators.required,
        Validators.minLength(4),
      ]),
      lastName: new FormControl(this.user.lastName, [
        Validators.required,
        Validators.minLength(4),
      ]),
      userName: new FormControl(this.user.userName, [
        Validators.required,
        Validators.minLength(4),
      ]),
      email: new FormControl(this.user.email, [
        Validators.required,
        EmailValidator
      ]),
      
      address1: new FormControl(this.user.address1, [
        Validators.required
      ]),
      address2: new FormControl(this.user.address2, [
        Validators.required
      ])
    });
  }
  onSubmit() {
    this.submitted = true;

    // stop here if form is invalid
    if (this.userForm.invalid) {
      return;
    }

    // display form values on success
    alert('SUCCESS!! :-)\n\n' + JSON.stringify(this.userForm.value, null, 4));
  }
  onReset() {
    this.submitted = false;
    this.userForm.reset();
  }
  get f() { return this.userForm.controls; }
  logFormValue() {
    console.log(this.userForm.value);
  }
  get firstName() { return this.userForm.get('firstName'); }
  get lastName() { return this.userForm.get('lastName'); }
  get userName() { return this.userForm.get('userName'); }
  get email() { return this.userForm.get('email'); }
  get address1() { return this.userForm.get('address1'); }
  get address2() { return this.userForm.get('address2'); }


}

We have to create the first template Html file with formGroup attribute directive named with userForm. Notice the template Html which contains [formGroup]="userForm".

Next, We have to create the constructor with FormBuilder in the component class.

We had created the FormGroup class and assigned userForm the same as in the Html template.

You might know how to apply the reactive forms. If you see the Html input field firstName. We need to apply the formControlName="firstName".

For each form filed, we have added validators with the creation of FormControl. Please notice the component class. Here we have applied the angular provided validators such as Validators.required and Validators.minLength for the form field firstName.

Reactive Forms Custom Validators

Here we will try to implement the Reactive Forms Custom Validators for email. We do have a pattern validator provided by angular. But we will try to write the custom validator for email.

email-validator.ts
import { FormControl } from "@angular/forms";

export function EmailValidator(control: FormControl) {
    let email = control.value;
    let EMAIL_REGEXP = /^[a-z0-9!#$%&\'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i;

    if (email != "" && (email.length <= 5 || !EMAIL_REGEXP.test(email))) {
        return {
            validateEmail: {
                valid: false
            }
        }
    }

}

Notice the BillingDetailsComponent we applied the same validator for the field email.

To get the entire example code you can refer to the Angular-ReactiveForms-ValidationExample-App repository

Leave A Reply