Reputation: 122
I am trying to make a custom validator for password but I don't get why I get the following error ERROR TypeError: Cannot read property 'f' of undefined
Below is my code:
registerForm: FormGroup;
submitted = false;
constructor(private Auth:AuthService, private router:Router,private
formBuilder:FormBuilder) { }
ngOnInit() {
this.registerForm = this.formBuilder.group({
userName: ['', Validators.compose([Validators.required,Validators.minLength(6),Validators.maxLength(30),Validators.pattern('^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+.[a-zA-Z0-9-.]+$')])],
email: ['', Validators.compose([Validators.required, Validators.email])],
password: ['', Validators.compose([Validators.required, Validators.minLength(6)])],
cpassword: ['', Validators.required,passwordMatch()] //paswordMatch triggers the error
},);
}
get f() { return this.registerForm.controls; }
function passwordMatch() {
if(this.f != undefined){
let passwordInput = this.f.password,
passwordConfirmationInput = this.f.cpassword;
if (passwordInput.value !== passwordConfirmationInput.value) {
return passwordConfirmationInput.setErrors({notequal: true})
}
else {
return passwordConfirmationInput.setErrors(null);
}
}
}
Upvotes: 1
Views: 2826
Reputation: 73337
this
is undefined
in your function, therefore you cannot reference it.
What I would add a sub formgroup, that would track both the value of password and confirm password, but if you want to go this route, modify your code as such:
// ...
// see the brackets also around the validators! No need to use Validators.compose
cpassword: ['', [Validators.required, passwordMatch]]
// ...
Then you would access the form group with parent
. Also you need to return either null
(valid) or an error:
function passwordMatch(input: FormControl) {
if (input.parent) {
let passwordInput = input.parent.get('password');
if (passwordInput.value !== input.value) {
return { notequal: true }
}
else {
return null;
}
}
}
DEMO: StackBlitz
But with this, we need to remember, if user modifies password field after modifying the confirmpassword and the passwords do not match, the form will still be considered valid. Here's a way to avoid this: password and confirm password field validation angular2 reactive forms
Upvotes: 1
Reputation: 21357
you can use input .root to get access to the parent of a control (your registerForm) try this, no need for f function
function passwordMatch(input: FormControl) {
if(input.root != undefined){
let passwordInput = input.root.controls.password,
passwordConfirmationInput = input.root.controls.cpassword;
if (passwordInput.value !== passwordConfirmationInput.value) {
return passwordConfirmationInput.setErrors({notequal: true})
}
else {
return passwordConfirmationInput.setErrors(null);
}
}
...
cpassword: ['', Validators.required, passwordMatch]
Upvotes: 0