Angular HTTP Interceptor подписывается на наблюдаемый, а затем возвращает next.handle, но выдает TypeError: Вы указали 'undefined' - PullRequest
1 голос
/ 16 апреля 2019

У меня есть HTTP-перехватчик, и перед каждым запросом я проверяю, не истек ли токен доступа, если это так, я подписываюсь на вызов http.post из моей службы, а затем подписываюсь на него, и когда я получаю новый токен доступа, я вызовите next.handle (запрос) так:

        this.auth.refreshAccessToken().subscribe((token: string) => {
          this.auth.newAccessToken = token;
          request = request.clone({
            setHeaders: {
              Authorization: `Bearer ${token}`
            }
          });
          return next.handle(request);
        });

Проблема в том, что он бросает TypeError: You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.

Что заставляет меня думать, что я неправильно выполняю этот вызов http.post.

РЕДАКТИРОВАТЬ 1: У меня не было возможности тщательно проверить это, но до сих пор кажется, что все работает. У меня был файл console.log перед возвратом всей карты, но он не работал, однако все остальное работало, и я обновляю currentUser везде / разрешения каждый раз, когда я получаю новый токен доступа и этот DID происходит, так что для всех намерений и целей это Кажется, работает, вот обновленный код:

          mergeMap(token => {
            this.auth.newAccessToken = token;
            request = request.clone({
              setHeaders: {
                Authorization: `Bearer ${token}`
              }
            });
            return next.handle(request);
          })

1 Ответ

1 голос
/ 16 апреля 2019

Вы бы не subscribe() внутри перехватчика, вместо этого вы бы вернули Observable<HttpEvent<any>>. Это можно сделать, используя конвейерные операторы RxJS ('rxjs/operators'), такие как tap (для таких побочных эффектов, как настройка newAccessToken) и switchMap или mergeMap в комбинация с pipe(), возвращающая наблюдаемое типа Observable<HttpEvent<any>> для удовлетворения интерфейса HttpInterceptor :

import { Injectable } from '@angular/core';
import {
  HttpEvent, HttpInterceptor, HttpHandler, HttpRequest
} from '@angular/common/http';
import { Observable } from 'rxjs';
import { switchMap, tap } from 'rxjs/operators';
import { AuthService } from './auth.service';

@Injectable()
export class AuthInterceptor implements HttpInterceptor {
  constructor(private auth: AuthService) { }

  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return this.auth.refreshAccessToken().pipe(
      tap(token => this.auth.newAccessToken = token), // side effect to set token property on auth service
      switchMap(token => { // use transformation operator that maps to an Observable<T>
        const newRequest = request.clone({
          setHeaders: {
            Authorization: `Bearer ${token}`
          }
        });

        return next.handle(newRequest);
      })
    );
  }
}

Вот пример в действии. Пожалуйста, проверьте журналы, чтобы увидеть информацию о выходе из системы.

Надеюсь, это поможет!

...