I am in a Angular proyect and I am using a reactive form. What I am trying to do is add my own validator. To do this, I need to check if the id exists in the database. For this reason I use an asynchronous validator. In case the id is already being used by another element, then it must return an error. Otherwise, the form will be valid.
This is the validator.
export class ValidadorOperationId {
static createValidatorOperationId(name, operationListService: OperationsListService, time: number = 500): AsyncValidatorFn {
return (control: AbstractControl): Observable<ValidationErrors> => {
return timer(time).pipe(
switchMap(() => operationListService.getOperationsByUuid(name, control.value)),
map(res => {
return res ? { operationIdExist: true } : null
}
)
);
};
}
}
And this is how I call to validator in my component.
this.fb.group({
value: [this.operationDetails['operationid'], [Validators.required], ValidadorOperationId.createValidatorOperationId(this.nombre,this.operationListService)]
})
The problem is that the control has status: pending
and I do not know what is wrong.
If you need some more code, just ask me.
Can anyone help me?
UPDATE 22/10/2020
I have checked that the status:pending
only appears when the service does not return anything (error 404)
Make sure that your getOperationsByUuid
return at least an observable or a promise even when you get a 404 error. That might be the reason why it get stuck in pending state because this function doesn't return anything, so your observable doesn't emit.
Notice the tap operator. If this log doesn't get print, that's the reason it stays in pending, because it never resolves.
export class ValidadorOperationId {
static createValidatorOperationId(name, operationListService: OperationsListService, time: number = 500): AsyncValidatorFn {
return (control: AbstractControl): Observable<ValidationErrors> => {
return timer(time).pipe(
switchMap(() => operationListService.getOperationsByUuid(name, control.value)),
tap(res => console.log('this should print')),
map(res => {
return res ? { operationIdExist: true } : null
}
),
take(1) // not useful if getOperationsByUuid is an http call (http calls always complete)
);
};
}
}