I'm trying to make a custom AsyncValidatorFn that will send a post request to the node.js/express server only after the user has finished typing in his email/username to check if it is unique, kinda like how Validators.required only pops up the error after you've clicked the input field, and then clicked out, without typing anything in.
I used this guide to help me start out and this is what I have for now:
In the form group in the component:
email: ["", [Validators.required, Validators.email], EmailUniqueValidator.createValidator(this.usersService) ]
The validator class itself:
export class EmailUniqueValidator{ static createValidator(usersService:UsersService):AsyncValidatorFn{ return(control: AbstractControl): Observable<ValidationErrors> =>{ return usersService.checkEmail(control.value).pipe( map((result:boolean) => result ? null: {emailUsed:true}) ) } } }
The users service function:
checkEmail(email:string){ const data={ email:email } const url = `${this.baseUrl}${ApiPaths.User}/checkEmail` return this.http.post(url,data).pipe( map((result)=>result["message"]=="email ok"?true:false) ) }
And the backend function for the emailCheck
emailCheck = (req:Request, res:Response)=>{ let emailLog = req.body.email; console.log("email check: "+ emailLog) User.findOne({email:req.body.email}, (err,result)=>{ if(err) console.log(err) if(result){ res.json({message:"duplicate email"}) console.log("duplicate email") } else{ res.json({message:"email ok"}) console.log("email ok") } }) }
I have seen How to delay the .keyup() handler until the user stops typing? and I think it should be helpful, but I can't figure out how to translate it into something that can work in my code.