Skip to content

Adding confirm password validation to Angular Reactive Forms? [closed]

I’m following this tutorial for how to validate confirm passwords with Angular Reactive Forms.

I created a Stackblitz for the implementation.

The implementation for the confirm password function comes from the tutorial and looks like this:

  passwordMatch(password: string, confirmPassword: string) {
    return (formGroup: FormGroup) => {
      const passwordControl = formGroup.controls[password];
      const confirmPasswordControl = formGroup.controls[confirmPassword];

      if (!passwordControl || !confirmPasswordControl) {
        return null;
      }

      if (
        confirmPasswordControl.errors &&
        !confirmPasswordControl.errors.passwordMismatch
      ) {
        return null;
      }

      if (passwordControl.value !== confirmPasswordControl.value) {
        confirmPasswordControl.setErrors({ passwordMismatch: true });
      } else {
        confirmPasswordControl.setErrors(null);
      }
    };
  }

If I try to add it to a composed validator like this:

    confirmPassword: new FormControl(
      '',
      Validators.compose([
        Validators.required,
        this.v.passwordMatch('password', 'confirmPassword'),
      ])
    ),

Angular creates an error that says:

ERROR
Error: Cannot read properties of undefined (reading 'password')

How do we add a validator that performs cross property validation?

Right now this Stackblitz Demo works:

https://stackblitz.com/edit/angular-ivy-f5dj86?file=src%2Fapp%2Fregistration.component.ts

Because the cross password validation is commented out:

    confirmPassword: new FormControl(
      '',
      Validators.compose([
        Validators.required,
        //        this.v.passwordMatch('password', 'confirmPassword'),
      ])
    ),

Answer

Since the validator needs access to both password control values to compare them, you have to use it as a FormGroup validator. So you just have to move the validator to the second argument of the FormGroup constructor like this

public registrationForm: FormGroup = new FormGroup({
    email: new FormControl(...),
    password: new FormControl(...),
    confirmPassword: new FormControl(...),
  },
  this.v.passwordMatch('password', 'confirmPassword') 
);

cheers