So what I'm trying to do is validate if username is already taken or not in my user edit form. Here is my form:
editForm= new FormGroup({
username: new FormControl('', [Validators.required, Validators.maxLength(60)], this.validateUser.bind(this)),
fullName: new FormControl('', Validators.maxLength(60)),
email: new FormControl('', Validators.maxLength(60)),
phoneNumber: new FormControl('', Validators.maxLength(60)),
}, { updateOn: "blur"});
In my validator I check if original username is changed before sending validation request by comparing it to variable which has user info loaded from server:
validateUser(control: FormControl): Observable<ValidationErrors | null> {
if(control.value != this.originUser.username){
return this.userService.validateUsername(control.value).pipe(map(res => {
return res['valid'] ? null : { invalidUsername: true};
}));
}
}
Everything works fine if I try to change username to already taken by another user and I get an error. Also if after this I change it to original username it also works fine and validation request is not sent.
My this.originUser
is populated in ngOnInit
and this happens after validator is called for the first time on form initialization so I still see a validation request with original username is sent and get an error when form loads with original username.
ngOnInit() {
this.userService.getOne(this.id).subscribe(user =>{
this.editForm.patchValue({
username: user.username,
fullName: user.fullName,
email: user.email,
phoneNumber:user.phoneNumber
});
this.originUser = user;
});
}
}
I cant figure out the logic how not to send validation request when validator is called for the first time when I open "Edit user" page
UPD:
I figured out how not to get error on form load by adding this.editForm.get('username').updateValueAndValidity();
after i load this.originUser
in ngOnInit
but unnecessary validation request is still sent when form loads.
So the solution was quite simple
Added control.dirty
to validator condition so request is never sent if user didnt change the input
validateUsername(control: FormControl): Observable<ValidationErrors | null> {
if(control.value != this.originUser.username && control.dirty){
return this.userService.validateUsername(control.value).pipe(map(res => {
return res['valid'] ? null : { invalidUsername: true};
}));
} else return of({});
}