Angular HTTP 拦截器订阅 observable 然后返回 next.handle 但抛出 TypeError : You provided 'undefined'

标签 angular typescript angular-httpclient angular-http-interceptors angular-observable

我有一个 HTTP 拦截器,在每次请求之前,我检查访问 token 是否已过期,如果是,我从我的服务订阅 http.post 调用,然后订阅它,当我获得新的访问 token 时,我将调用下一个。像这样处理(请求):

        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:我还没有机会彻底测试这个,但到目前为止似乎一切正常。在返回整个 map 之前我有一个 console.log 但它没有触发,但是,其他一切都有效,并且每次我获得新的访问 token 并且 DID 发生时,我都会在任何地方更新 currentUser/权限,因此出于所有意图和目的,它似乎工作,这是更新的代码:
          mergeMap(token => {
            this.auth.newAccessToken = token;
            request = request.clone({
              setHeaders: {
                Authorization: `Bearer ${token}`
              }
            });
            return next.handle(request);
          })

最佳答案

你不会subscribe()在拦截器内部,你会返回一个 Observable<HttpEvent<any>> .这可以通过使用 RxJS 可管道操作符 ( 'rxjs/operators' ) 来完成,例如 tap (对于设置 newAccessToken 等副作用)和 switchMapmergeMap结合 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);
      })
    );
  }
}

这是一个 example在行动。请查看日志以查看正在注销的关键信息。

希望这有帮助!

关于Angular HTTP 拦截器订阅 observable 然后返回 next.handle 但抛出 TypeError : You provided 'undefined' ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55711337/

相关文章:

javascript - 使用 Angular Router 获取 URL

reactjs - React FunctionComponent 的 TypeScript 类型,它只返回一个 IntrinsicElement

javascript - StaticInjectorError [HttpClent] : Function/class not supported

node.js - Angular 8 ajax有时很慢

angular - 使用数据 bool 值展开/折叠 Material 树(Angular 7)

angular - 如何在 angular-google-maps 中以编程方式打开/关闭时髦的信息窗口?

Angular 2 Universal - 存储全局变量

typescript - 在 TypeScript 中使用 ENUM 有什么意义?

javascript - 尝试使用我自己的 ReactDataGrid 默认值创建可重用的 DataGrid 组件,但 Typescript 给我错误

angular - 如何同时接收字节和字符串数据?