Angular - How to validate two pairs of fields independently

Viewed 37

I want to validate two pairs of fields independently.

One pair of fields is the password. I want to check that they are the same.

The second pair of fields is the email address. I want to check that they are the same.

The method below doesn't work or I just don't know how to do it.

I can not. Tell me how to do it?

        export class RegistrationComponent implements OnInit {

          loginForm!:FormGroup;


          constructor(private formBuilder: FormBuilder) {
          }

          ngOnInit(): void {

            this.loginForm = this.formBuilder.group({

              email1: ['', {
                validators: [Validators.required]
              }],

              email2: ['', {
                validators: [Validators.required]
              }],

              password1: ['', {
                validators: [Validators.required]
              }],

              password2: ['', {
                validators: [Validators.required]
              }]

            },

            {validators: this.matchData('email1','email2', 'password1', 'password2')});

          }

          get email1() {
            return this.loginForm.controls['email1'];
          }

          get email2() {
            return this.loginForm.controls['email2'];
          }

          get password1() {
            return this.loginForm.controls['password1'];
          }

          get password2() {
            return this.loginForm.controls['password2'];
          }


          public matchData(email1: any, email2: any, password1: any, password2: any): ValidatorFn {

            return (control: AbstractControl): ValidationErrors | null => {

              let passwordOne = control.get(password1)?.value;
              let passwordTwo = control.get(password2)?.value;

              let emailOne = control.get(email1)?.value;
              let emailTwo = control.get(email2)?.value;

              if (passwordOne != passwordTwo) {
                return { 'noMatchPass': true }
              }
                return null

            }
          }


        }

HTML

    <input type="email" formControlName="email1">
    <div *ngIf="email1.errors?.['required']"> Email address required </div>

    <input type="email" formControlName="email2">
    <div *ngIf="email2.errors?.['required']"> Email address required </div>
    <div *ngIf="loginForm.hasError('noMatchEmail')">Email address does not match</div>


    <input type="password" formControlName="password1">
    <div *ngIf="password1.errors?.['required']"> Password required </div>

    <input type="password" formControlName="password2">
    <div *ngIf="password2.errors?.['required']"> Password required </div>
    <div *ngIf="loginForm.hasError('noMatchPass')"> Passwords do not match </div>
1 Answers

You can create a custom validator, for an example this code below is a custom validator for match.validator.ts:

import {
  AbstractControl,
  FormGroup,
  ValidationErrors,
  ValidatorFn,
} from "@angular/forms";
export const matchValidator = (
  matchWith: string,
  message?: string
): ValidatorFn => {
  return (control: AbstractControl): ValidationErrors | null => {
    const value = control.value;
    if (value) {
      const formGroup = control.parent as FormGroup;
      const defaultError = {
        value,
        expectedValue: "",
      };
      if (formGroup && formGroup.get(matchWith) instanceof AbstractControl) {
        const matchValue = formGroup.get(matchWith)?.value;
        if (value !== matchValue) {
          defaultError.expectedValue = matchValue;
          return {
            ...defaultError,
            message: message,
          };
        }
        formGroup.get(matchWith)?.valueChanges.subscribe(() => {
          control.updateValueAndValidity();
        });
      } else {
        if (control.value !== matchWith) {
          defaultError.expectedValue = matchWith;
          return {
            ...defaultError,
            message: message,
          };
        }
      }
    }
    return null;
  };
};

Now you can use that's match validator like an angular validator.

For an example:

this.formGroup = new FormBuilder().group({
  email: [null],
  confirmEmail: [
    null,
    Validators.compose([
      matchValidator('email', 'Confirm email does not match with email'),
    ]),
  ],
  password: [null],
  confirmPassword: [
    null,
    Validators.compose([
      matchValidator(
        'password',
        'Confirm password does not match with password'
      ),
    ]),
  ],
});

Live Code:: https://stackblitz.com/edit/angular-ivy-rltfm5?file=src/app/app.component.ts

Live Preview:: https://angular-ivy-rltfm5.stackblitz.io

I hope it can help.

Related