In angular, I have an async validator for a user registration form that checks if an email already exists in database. It calls an endpoint of my Rest API with HEAD method, that returns a Http 200 Ok status if the email is found and a 404 if it's not found (I'm not sure that it's a proper Rest practice thought). But i can't figure out how to turn that http call into an Observable that my validator is expecting.
My layers for this operation without taking in consideration the form is :
AsyncValidator -> authService.isEmailTaken() -> dataManagementService.headCall()
My validator:
export const uniqueEmailValidator = (authService: AuthService, time: number = 500) => {
return (input: FormControl) => {
return timer(time).pipe(
switchMap(() => authService.isEmailTaken(input.value)),
map(isTaken => {
console.log(isTaken);
return isTaken ? { uniqueEmail: true } : null;
})
);
};
};
AuthService.ts:
public isEmailTaken(email: string): Observable<boolean> {
const params = new Map();
params.set('email', email);
return this.dataManagementService.headResource(
this.authURI + this.registerURI,
params
).pipe(
map(
() => {
console.log('success');
return true;
},
() => {
console.log('error');
return false;
}
)
);
}
My http call :
public headResource(url: string, paramMap?: Map<string, string>): Observable<any> {
const params = this.getHttpParams(paramMap);
console.log('Sending HEAD request to server :');
console.log(this.baseUrl + url);
return this.httpClient.head(
this.baseUrl + url,
{params}
);
}
My validator should be valid when the status code is 404 and invalid when is 200, but though it works on 200, it has no efffect on 404. I'm not very confortable using rxjs.
Is there something i'm missing ? Or should i change the approach with the backend service sending a boolean, or maybe a 204 status code if not found ?
Thanks a lot for help!
============== EDIT =======================
Thanks to martin comment i managed to make it works by changing the isEmailTaken method of my authService, and using catchError:
public isEmailTaken(email: string): Observable<boolean> {
const params = new Map();
params.set('email', email);
return this.dataManagementService.headResource(
this.authURI + this.registerURI,
params
).pipe(
map(
() => {
return true;
}),
catchError(error => {
if (error.status === 404) {
return of(false);
}
})
);
}