How to cancel current request in interceptor - Angular 4

Viewed 29731

As you know it's possible to use Interceptors in new versions of Angular 4.

In mine, I want to cancel a request in interceptor in some conditions. So is it possible? Maybe what I should ask is: which way I should do that?

It'll also be OK if I find a way to rewrite some response to the request instead of canceling it.

8 Answers

I think all you have to do to cut the interceptor chain is to simply return an empty Observable like so:

import { EMPTY } from 'rxjs';

intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
  if (stopThisRequest) {
    return EMPTY;
  }

  return next.handle(request);
}

This is just a slight variant of RVP's answer

import { NEVER } from 'rxjs';

intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
  if (stopThisRequest) {
    return NEVER;
  }

  return next.handle(request);
}

I used NEVER instead of EMPTY to avoid dealing with undefined values in my subscriptions (or promises).

Use NEVER if you don't want your subscription callback to be invoked

To Angular 6, you need can user the following structure to return a empty Observable:

import {Observable} from 'rxjs';
import {empty} from 'rxjs/internal/Observer';

//...

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    if (stopThisRequest) {
        return Observable.create(empty);
    } else {
        return next.handle(req);
    }
}

As suggested above, there is more optimal way to handle the error with custom response

import { throwError, Observable } from 'rxjs';
import { HttpEvent } from '@angular/common/http';

intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
  if (authFailedDummy(request)) {
    return throwError(new Error('Authorization error: The request did not go through'));
  }
  return next.handle(request);
}

Hey I think i am late to the party but wanna share some additional knowledge

If you wanna cancel requests after a certain timeout you can use rxjs timeout operator in intercepter, and it will work for every requests.

  intercept(req: HttpRequest<any>, next: HttpHandler):Observable<HttpEvent<unknown>> 
    {
    return next.handle(req).pipe(timeout(30000), 
    catchError((error: HttpErrorResponse) => {
      return throwError({ error: error.name, message: error.message});
    })) as Observable<HttpEvent<unknown>>
    }

let sub = this.http.get(url, {headers: reqHeaders})
            .subscribe(
                (res) => {
                    res = res.json();
                }
            );

sub.unsubscribe();
Related