Search code examples
angularrxjsrxjs6angular-http-interceptors

Angular: How to show something on slow HTTP response


In my angular apps, I want to show a text/modal that have a cancel and reload button, when the server responds slowly.

If the user click cancel, current http request will be cancelled. If the user click reload, current http request will be retried. If the text/modal already shown and the HTTP request already respond/completed, then the text/modal should disappear.

I have an idea using HTTP interceptor, RxJS, and global service, but implementing it is not that easy.

Is there anyone who have an idea, how to do this the right way?

EDIT: Oh and I want to make it a generic module so every http request can be cancellable or reloadable. So every page could have this functionality


Solution

  • Cancel/abort all pending HTTP requests with takeUntil

    You can use takeUntil to stop an ongoing request, because a request from HttpClient returns an observable you can do it quite easy:

    TS

    userStop$: Subject<boolean> = new Subject<boolean>();
    
    makeRequest() {
        this.userStop$.next(false);
        // Service Call
        this.apiService.makeRequest().pipe(
            takeUntil(this.userStop$)
        ).subscribe(...);
    }
    
    handleUserStop() {
        this.userStop$.next(true);
    }
    
    

    When you change the userStop$ to true with a button click for example it will stop. To retry you can simply recall the service method and set the userStop$ to false;

    If you want to retry the request after it failed, you can use retry(x).

    this.apiService.makeRequest().pipe(
        //retry 2 times on error
        retry(2)
    ).subscribe(...);
    

    You can also checkout this: How to cancel/unsubscribe all pending HTTP requests angular 4+

    For more information: https://www.learnrxjs.io/operators/filtering/takeuntil.html