On our registration form we have a password field and a confirmPassword field.
We want to validate that the confirmPassword field matches the password field prior to enabling the submit button for the form.
If the passwords do not match then the mat-error notification below the confirmPassword field will display a message indicating this.
Approach
Matching the Passwords
First within our validation.service.ts service we will create a factory function used to produce the ValidatorFn instance that will check whether the passwords match.
passwordMatch(password: string, confirmPassword: string): ValidatorFn {
return (formGroup: AbstractControl): { [key: string]: any } | null => {
const passwordControl = formGroup.get(password);
const confirmPasswordControl = formGroup.get(confirmPassword);
if (!passwordControl || !confirmPasswordControl) {
return null;
}
if (
confirmPasswordControl.errors &&
!confirmPasswordControl.errors.passwordMismatch
) {
return null;
}
if (passwordControl.value !== confirmPasswordControl.value) {
confirmPasswordControl.setErrors({ passwordMismatch: true });
return { passwordMismatch: true };
} else {
confirmPasswordControl.setErrors(null);
return null;
}
};
}
If the there are no errors then null is returned. If the passwords do no match we set the passwordMismatch error on the confirmPasswordControl.
Creating the Reactive Form
Note that the passwordMatch function is passed in as the second argument in the FormGroup constructor:
public registrationForm: FormGroup = new FormGroup(
{
password: new FormControl('', [
Validators.required,
Validators.minLength(8),
Validators.maxLength(32),
this.v.passwordMinLowerCaseLettersValidator(),
]),
confirmPassword: new FormControl(
'',
Validators.compose([Validators.required])
),
},
this.v.passwordMatch('password', 'confirmPassword')
);
Creating the Reactive Form Template
<mat-card style="min-width: 10rem; max-width:30rem;margin: 2rem;">
<form
fxLayoutAlign="stretch"
fxLayout="column"
[formGroup]="registrationForm"
(ngSubmit)="submit()"
>
<mat-form-field>
<input
matInput
type="password"
placeholder="Password"
formControlName="password"
/>
<mat-hint *ngIf="!passwordValue">Example @123PASSWord</mat-hint>
<mat-error *ngIf="passwordControl.invalid">{{
getPasswordError()
}}</mat-error>
</mat-form-field>
<mat-form-field>
<input
matInput
type="password"
placeholder="Confirm Password"
formControlName="confirmPassword"
/>
<mat-error *ngIf="confirmPasswordControl.invalid"
>Passwords do not match
</mat-error>
</mat-form-field>
<button mat-button type="submit" [disabled]="!registrationForm.valid">
Register
</button>
</form>
</mat-card>