I wrote a simple custom Validator to compare two password fields and signal an error if they don't match. Here it is:
@Directive({
selector: '[appMatchPassword]',
providers: [
{ provide: NG_VALIDATORS, useExisting: MatchPasswordDirective, multi: true }
]
})
export class MatchPasswordDirective implements Validator {
@Input('appMatchPassword') otherControl: string = '';
constructor() { }
registerOnValidatorChange(fn: () => void): void {
}
validate(control: AbstractControl): ValidationErrors | null {
const compareTo = control.parent?.get(this.otherControl);
if (!compareTo) return null;
if (compareTo?.value !== control.value) return {
appMatchPassword: true
}
return null;
}
}
The template references it like this:
<mat-form-field>
<mat-label>Password</mat-label>
<input matInput type="password" name="password" [(ngModel)]="user.password"
required minlength="4" #iPassword="ngModel">
<mat-error *ngIf="iPassword.errors?.required">Password Required.</mat-error>
<mat-error *ngIf="iPassword.errors?.minlength">Minimum 4 characters</mat-error>
</mat-form-field>
<mat-form-field>
<mat-label>Verify Password</mat-label>
<input matInput type="password" name="vpassword" [(ngModel)]="vpassword"
required appMatchPassword="password" #fvp="ngModel">
<mat-error *ngIf="fvp.errors?.appMatchPassword">Passwords do not match</mat-error>
</mat-form-field>
This works as desired if the user puts a value into the password
field and a different value in the vpassword
field. The error is displayed and goes away if the user corrects the value in the vpassword
field.
However, if the user goes back and edits the password
field the error does not go away. The validator only gets called after its own AbstractControl changes value.
Is there any good way to trigger the Validator when the password
field gets changed?