Angular HTTP Interceptor订阅observable然后返回next.handle但抛出TypeError:你提供了'undefined'

问题描述 投票:1回答:1

我有一个HTTP拦截器,在每次请求之前我检查访问令牌是否过期,如果是,我订阅了来自我的服务的http.post调用然后订阅它,当我得到一个新的访问令牌时,我调用下一个。 handle(request)像这样:

        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,但它没有触发,但是,其他一切都工作了,每当我得到一个新的访问令牌并且DID发生时,我更新currentUser到处/权限,所以对于所有意图和目的它似乎工作,这是更新的代码:

          mergeMap(token => {
            this.auth.newAccessToken = token;
            request = request.clone({
              setHeaders: {
                Authorization: `Bearer ${token}`
              }
            });
            return next.handle(request);
          })
angular typescript angular-httpclient angular-http-interceptors angular-observable
1个回答
1
投票

你不会在拦截器内部使用subscribe(),而是返回一个Observable<HttpEvent<any>>。这可以通过利用RxJS可管理运算符('rxjs/operators')(例如tap设置副作用)和newAccessTokenswitchMap结合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); }) ); } } 在行动。请查看日志以查看正在注销的关键信息。

希望这有帮助!

© www.soinside.com 2019 - 2024. All rights reserved.