top of page

How to Cancel API Requests If You Are Using Observable Pipe in Angular



In an e-mail sign up form, async validation was used to check if typed username was taken or not. “updateOn” value was set as ‘blur’ but changing it to ‘change’ would make it more user friendly.


updateOn” option’s possible values are ‘change’, ‘blur’ and ‘submit’. You can read more about “updateOn” option here.


By changing it to ‘change’, more API requests will be made because now we will be querying if the username is available every time the user types in or deletes a new character.


Since there will be much more requests and network problems where previous requests will take longer than newer ones, it would be nice to cancel the previous request before making a new one.


In the validation code, pipe was used to decide the value of show error flag variable. It would also be possible to convert to subscribe -> response, error, completion handler function style like:



Instead, I kept the current flow but added “takeUntil” method as suggested here by user184994.

You can also check the example under “Unsubscribing Declaratively with takeUntil” title here.


This is my implementation (search for cancelCheckUsername$ for its usage):

import{of, EMPTY, Subject}from 'rxjs';

...

cancelCheckUsername$: Subject<boolean> = new Subject<boolean>();

...

ngOnDestroy()
{
    this.cancelCheckUsername$.unsubscribe();
}

...

createForm(): FormGroup
{
    return this.fb.group(
    {
        username: new FormControl(this.getPrefix(this.storage.email),
        {
            asyncValidators: this.checkEmailValidator(),
            updateOn: 'change',
        }),
        // other fields
      }
   );
}
            
checkEmailValidator(): any 
{
    return(control: AbstractControl)=>
    {
        this.cancelCheckUsername$.next(true);
        const email=control.value+this.postfix;
        if(control.value.length>0)
        {
            return this.registerService.checkEmail(email).pipe(
                map((response: HttpResponse<any>)=>    
                {
                    if(response.status===200)
                    {
                        this.showErrorMessage=false;
                        return null;
                    }
                }),
                takeUntil(this.cancelCheckUsername$),
                catchError((response: HttpErrorResponse)=>
                {
                    this.showErrorMessage=true;
                    if(response.status===412)
                    {
                        this.errorMessage='EMAIL_TAKEN_BEFORE';
                    }
                    // other logic
                    return response.status===412 ? of({'emailNotValid': 
                    control.value}) : EMPTY;
                })
            );
        } else {
            return EMPTY;
        }
    };
}

You can check if the field is valid by:

form.controls['username'].hasError('emailNotValidated')

To show your error / info message:

<div *ngIf="!showErrorMessage; else error">




Source: Medium - Señorita Developer


The Tech Platform

0 comments
bottom of page