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'),
])
),
Advertisement
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