Angular2:Guard 中的嵌套 Observables

问题描述 投票:0回答:2

我有一名守卫保护某条路线。在

canActive
方法中,我需要发出两个 http 请求,其中根据第一个请求的响应触发第二个请求。但是,第二个请求从未发出,我认为它与返回 Observables 的嵌套构造有关。

1 canActivate(route: ActivatedRouteSnapshot,
2          state: RouterStateSnapshot) : Observable<boolean>|boolean {
3  return this.provider.getA().map(
4    dataA => {
5      return this.provider.getB().map(
6        dataB => {
7          return (dataB.allowed);
8        }
9      );
     }
   );  
 }

getA() 和 getB() 都返回以下内容:

getA() : Observable<any> {
  return this.http.post(URL,payload).
                   map(response => response.json());

};

代码已简化,但您可以假设 getA() 和 getB() 工作正常。当调用 Guard 时,getA() 可以通过网络正常发送,但 getB() 永远不会发送。调试器在第 5 行静默退出。

还有一件事,TypeScript 显示了一条警告,可能已经告诉了我解决方案,但是,我对 Observables 太菜鸟了,尤其不知道如何处理它:

Observable<Observable<boolean>>' is not assignable 
to type 'Observable<boolean>'

猜测一下,Observables 的构造永远不会解析,这就是为什么没有警告,我一直等到时间结束。我天真的想法是,只要任何 Observable 将返回一个布尔值(如第 7 行中所做的那样),订阅者就会知道如何处理它。

我很高兴阅读您的提示。去睡觉了...

angular typescript router observable guard
2个回答
4
投票

您应该在这里使用

switchMap

return this.provider.getA().switchMap(
  dataA => {
    return this.provider.getB().map(
      dataB => {
        return (dataB.allowed);
      }
    );
  }
);

在您的代码中,您正在创建一个 Observables 的 Observables。

switchMap
扁平化该结构并通过 A 发射 B 的发射项。


0
投票

更新@j2l4e 分享的解决方案

大多数 RxJS 运算符现在都是可管道化的,因此如果没有 pipe() 将会导致错误/警告。

管道解决方案()

  canActivate(): boolean | Observable<boolean> | Observable<Observable<boolean>> {
    return this.httpClient
      .get('https://jsonplaceholder.typicode.com/todos')
      .pipe(
        switchMap((dataA: any) => {
          console.log('dataA :: ', dataA);
          return this.httpClient
            .get('https://jsonplaceholder.typicode.com/posts')
            .pipe(
              map((dataB: any) => {
                // add your logic here...
                console.log('data b', dataB);
                return false;
              })
            );
        })
      );
  }

更多信息请参阅官方文档:

  1. https://rxjs.dev/guide/operators
  2. https://rxjs.dev/api/index/function/pipe
  3. https://rxjs.dev/api/operators/switchMap
© www.soinside.com 2019 - 2024. All rights reserved.