Musaffar Patel
Musaffar Patel

Reputation: 1372

HttpInterceptor Retry request on snackbar action

I'm using the HttpInterceptor class to centrally catch and handle unexpected errors from the server. I've managed to succeed in accomplishing this for the most part but want to expand this a little by allowing the user to retry certain requests based on the response code. However, I'm not sure how to go about this. Here is what I have so far:

    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        // Add HTTP Auth to access the API
        request = request.clone({
            setHeaders: {
                Authorization: 'Basic ' + btoa('my_api_key:')
            }
        });

        // handle response
        return next.handle(request).pipe(
            catchError((error: HttpErrorResponse, caught: Observable<any>) => {
                console.log('error occurred');

                if (error.status === 401) {
                    const snackBarRef = this.snackBar.open('Error occurred', 'Retry', {
                        duration: 7000
                    });

                    snackBarRef.onAction().subscribe(() => {
                    });
                    return EMPTY;
                }
                return throwError(error.statusText);
            })
        );
    }

So far, it catches the error as expected and if it is a 401 error the snackbar is displayed along with retry action. How would I issue a retry from within the snackbar action?

Upvotes: 4

Views: 720

Answers (2)

yurzui
yurzui

Reputation: 214295

You can use second parameter caught passed to catchError pipe to retry the same request.

return snackBarRef.onAction().pipe(concatMap(() => caught)); 

Stackblitz Example

Upvotes: 2

Jows
Jows

Reputation: 461

I guess you could reissue the exact same request with the "request()" method of HttpClient service as well:

intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    // Add HTTP Auth to access the API
    request = request.clone({
        setHeaders: {
            Authorization: 'Basic ' + btoa('my_api_key:')
        }
    });

    // handle response
    return next.handle(request).pipe(
        catchError((error: HttpErrorResponse, caught: Observable<any>) => {
            console.log('error occurred');

            if (error.status === 401) {
                const snackBarRef = this.snackBar.open('Error occurred', 'Retry', {
                    duration: 7000
                });

                snackBarRef.onAction()
                 .pipe(
                   switchMap(_ => this.httpClient.request(request))
                 ).subscribe();
                return EMPTY;
            }
            return throwError(error.statusText);
        })
    );
}

Upvotes: 1

Related Questions