I\'m trying to implement a custom validator to check if the password and password confirm are equal. The problem is that the validator is getting undefined password and conf
Just for the variety, I'm adding one more way to do this. Basically, I created a simple custom validator that takes the original control (first entered field) and checks it's value with the re-entry control (second control).
import { AbstractControl, ValidatorFn } from "@angular/forms";
export abstract class ReEnterValidation {
static reEnterValidation(originalControl: AbstractControl): ValidatorFn {
return (control: AbstractControl): { [s: string]: boolean } => {
if (control.value != originalControl.value) {
return { 'reentry': true };
}
};
}
}
You can either set this validator initially when creating a new form control:
control1 = new FormControl('', ReEnterValidation.reEnterValidation(control2));
Or, you can set it afterwards:
control.setValidators(ReEnterValidation.reEnterValidation(this._newPinControl));
control.updateValueAndValidity();
In the view, you can show the errors as following:
<!-- Confirm pin validation -->
<div *ngIf="control2.invalid && (control2.dirty || control2.touched)">
<div *ngIf="control2.errors.reentry">
The re-entered password doesn't match. Please try again.
</div>
</div>
this.myForm = this.fb.group({
userEmail: [null, [Validators.required, Validators.email]],
pwd: [null, [Validators.required, Validators.minLength(8)]],
pwdConfirm: [null, [Validators.required]],
}, {validator: this.pwdConfirming('pwd', 'pwdConfirm')});
pwdConfirming(key: string, confirmationKey: string) {
return (group: FormGroup) => {
const input = group.controls[key];
const confirmationInput = group.controls[confirmationKey];
return confirmationInput.setErrors(
input.value !== confirmationInput.value ? {notEquivalent: true} : null
);
};
}
There are two types of validators: FormGroup validator and FormControl validator. To verify two passwords match, you have to add a FormGroup validator. Below is my example:
Note: this.fb is the injected FormBuilder
this.newAccountForm = this.fb.group(
{
newPassword: ['', [Validators.required, Validators.minLength(6)]],
repeatNewPassword: ['', [Validators.required, Validators.minLength(6)]],
},
{validator: this.passwordMatchValidator}
);
passwordMatchValidator(frm: FormGroup) {
return frm.controls['newPassword'].value === frm.controls['repeatNewPassword'].value ? null : {'mismatch': true};
}
and in the templeate:
<div class="invalid-feedback" *ngIf="newAccountForm.errors?.mismatch && (newAccountForm.controls['repeatNewPassword'].dirty || newAccountForm.controls['repeatNewPassword'].touched)">
Passwords don't match.
</div>
The key point here is to add the FormGroup validator as the second parameter to the group method.