Reputation: 1518
I'm trying to set up a validator on a form in my Angular app to check if both entered passwords are the same. I think the Angular documentation doesn't explain this well.
This is a part of my sign up component:
export function passwordMatchValidator(password: string): ValidatorFn {
return (control: AbstractControl): { [key: string]: any } => {
return password !== control.value ? { mismatch: true } : null;
};
}
@Component({
selector: 'app-sign-up-form',
templateUrl: './sign-up-form.component.html'
})
export class SignUpFormComponent {
signUpForm: FormGroup;
constructor(
private fb: FormBuilder
) {
this.signUpForm = this.fb.group({
email: [null, [Validators.required, Validators.email]],
password: [null, [Validators.required, Validators.minLength(6)]],
passwordRepeat: [
null,
[Validators.required, Validators.minLength(6), passwordMatchValidator(this.password.value)]
]
});
}
get email() {
return this.signUpForm.get('email');
}
get password() {
return this.signUpForm.get('password');
}
get passwordRepeat() {
return this.signUpForm.get('passwordRepeat');
}
I want to be able to use the following code in the component's template:
<div *ngIf="passwordRepeat.errors.mismatch">
The passwords are not the same.
</div>
Unfortunately something is not right because in the console I get a weird error saying actually nothing useful (TypeError: this.signUpForm is undefined)
Hope you can help me.
---Updated---
constructor(
private fb: FormBuilder
) {
this.signUpForm = this.fb.group({
email: [null, [Validators.required, Validators.email]],
password: [null, [Validators.required, Validators.minLength(6)]],
passwordRepeat: [
null,
[Validators.required, Validators.minLength(6), passwordMatchValidator(this.password.value)]
]
});
}
passwordMatchValidator(password: string): ValidatorFn {
return (control: AbstractControl): ValidationErrors => {
return password !== control.value ? { mismatch: true } : null;
};
}
I tried to remove the fn argument and mess around in the validator fn to get the original password but none of my attempts worked.
Upvotes: 0
Views: 744
Reputation: 13734
When you set up the validator here:
passwordRepeat: [
null,
[Validators.required, Validators.minLength(6), passwordMatchValidator(this.password.value)]
]
The then-current value of this.password.value
is what gets passed into your validator -- which is probably just null or an empty string. And that's the only thing the repeated password will ever get compared with. What later gets entered into the original password field isn't going to be tracked.
You need a validator that's in the scope of your SignUpFormComponent
instance that can compare against the original password field as it changes.
Update:
What I'm thinking should work is something like this:
constructor(
private fb: FormBuilder
) {
this.signUpForm = this.fb.group({
email: [null, [Validators.required, Validators.email]],
password: [null, [Validators.required, Validators.minLength(6)]],
passwordRepeat: [
null,
[Validators.required, Validators.minLength(6), passwordMatchValidator(this)]
]
});
}
static passwordMatchValidator(comp: SignUpFormComponent): ValidatorFn {
return (control: AbstractControl): ValidationErrors => {
return comp.password.value !== control.value ? { mismatch: true } : null;
};
}
Upvotes: 1