简体   繁体   中英

How to cancel current request in interceptor - Angular 4

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? or maybe what should I ask is, Which way I should do that?

Also It will be Ok! if I found a way to rewrite some response to the request instead of canceling it.

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);
}

Inspired by @RVP answer I have found out that it's possible to cut the chain with an error in the same simple way using Observable.throw()

//...
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    if (stopThisRequestWithError) {
        return Observable.throw('Error message');
    } else {
        return next.handle(req);
    }
}

This avoids fulfilling response promises with undefined values.

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);
    }
}

@RVP's code will work, We can do one more thing for same.

add return only, it will also work

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
          if(helper.isTokenExpired(tokenVal)){
              return;
          }
        .
        . <{code}>
        .

    }

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();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM