Angular ReactiveForm – Cross form validation


Cross form validation

Angular – ReactiveForm Simple Validation and Angular ReactiveForm – Custom Validator explain how to use validation in one field.

But we sometimes are required to check multiple fields at the same time.


To set one validation to multiple form control, we can use formgroup.

Above 2 articles, we use one fromgroup, In form group, we can get formcontrol using get method. So, in formgroup we can get control.

We can use sub form group in form group. To use this, we can set grouping in form group.

As an example, let’s start to explain email confirmation form.


We create one form with 2 email input field.

2 email input should be same (email and email confirmation)

Let’s see sample codes to support this.


import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators, AbstractControl } from '@angular/forms';

  selector: 'app-root',
  templateUrl: './crossformvalidatorsample.component.html',
  styleUrls: ['./crossformvalidatorsample.component.css']
export class CrossformvalidatorsampleComponent implements OnInit {

  testForm: FormGroup;

  constructor(private fb: FormBuilder) { }

  ngOnInit(): void {
    this.testForm ={
        email: ['', [Validators.required,]],
        confirm: ['', Validators.required],
      }, {validator: emailMatcher})

  save() {



function emailMatcher(c: AbstractControl) : { [key: string] : boolean } | null {
  const emailControl = c.get('email');
  const confirmControl = c.get('confirm');
  if (emailControl.pristine || confirmControl.pristine) {
     return null;
  if (emailControl.value === confirmControl.value) {
     return null;
  return { 'match': true }; 

this codes has a lot of new.

We create form group of form group.

emailGroup is sub form group under testForm.

email and confirm is email input text field, and grouped.

As group validator, emailMatcher is validator for above 2 input text.

emailMatcher is validator function. Style is same as general custom validator.

Get form control from AbstractControl, and check both parameters.

value is same or not.

Next, let’s take a look html codes


<h2>Custom Builder Validation</h2>
<form (ngSubmit)="save()" [formGroup]="testForm">

    <div formGroupName="emailGroup">
        <input id="emailId" type="email"
            [ngClass]="{'is-valid': (testForm.get('emailGroup').get('email').touched || testForm.get('emailGroup').get('email').dirty)}"/>
        <input id="confirmEmailId" type="email"
            [ngClass]="{'is-valid': (testForm.get('emailGroup').get('confirm').touched || testForm.get('emailGroup').get('confirm').dirty)}"/>
        <span class="invalid-feedback">
        <span *ngIf="testForm.get('emailGroup').errors?.match">
            Does not match

    <button class="btn btn-primary mr-3"

Not difficult, to get nested control, use get method, and each control is under get.get.