Angular 路线 guard/resolver - 类型 'Observable<boolean | object[]>' 不可分配给类型 'Observable<boolean>'

Angular route guard/resolver - Type 'Observable<boolean | object[]>' is not assignable to type 'Observable<boolean>'

我正在使用路由守卫(或解析器,我曾尝试使用其中任何一个但得到了相同的错误),我希望将 Observable 作为 return 值:

canActivate(): Observable<boolean> {
    return this.store.pipe(
      select(fromUserProfileState.getUserProfiles),
      tap((loaded: UserProfile[]) => {
        if (!loaded || loaded.length == 0) {
          this.store.dispatch(new fromUserProfileActions.LoadUPs());
        } else {
          return of(true);
        }
      }),
      filter((loaded: UserProfile[]) => loaded.length > 0),
      first()
    );
  }

然而,这不是 return 可观察的,它是 return 可观察的,这是不可接受的。如何将 rxjs (v 6.5.5) 运算符调整为 return Observable only?

试试这个:

canActivate(): Observable<boolean> {
  return this.store.pipe(
    select(fromUserProfileState.getUserProfiles),
    // Convert the information from UserProfiles to a boolean
    // Thils will also be used to authorize the navigation
    map((loaded: UserProfile[]) => !!(loaded && loaded.length)),
    // dispatch an action is no user profile has been loaded
    tap((isLoaded: Boolean) => {
      if (!isLoaded) {
        this.store.dispatch(new fromUserProfileActions.LoadUPs());
      }
    }),
    // complete the observable
    take(1)
  );
}

tap 用于产生副作用,但 returns 与源中的观察结果相同。

不需要 first() 因为 canActivate() 会取消订阅

也许您可以中断导航,除非 LoadUPs() 准备好所有数据并作为新的副作用重试导航

canActivate(): Observable<boolean> {
    return this.store.pipe(
      select(fromUserProfileState.getUserProfiles),
      tap((loaded: UserProfile[]) => {
        if (!loaded || loaded.length == 0) {
          this.store.dispatch(new fromUserProfileActions.LoadUPs());
        }
      }),
      map((loaded: UserProfile[]) => {
        if (!loaded || loaded.length == 0) {
          return false;
        } else {
          return true;
        }
      })
    );
  }

感谢@julianobrasil 这对我的案例有用:

canActivate(): Observable<boolean> {
    return this.store.pipe(
      select(fromUserProfileState.getUserProfiles),
      // Convert the information from UserProfiles to a boolean
      // Thils will also be used to authorize the navigation
      map((loaded: UserProfile[]) => !!(loaded && loaded.length)),
      // dispatch an action is no user profile has been loaded
      tap((isLoaded: boolean) => {
        if (!isLoaded) {
          this.store.dispatch(new fromUserProfileActions.LoadUPs());
        }
      }),
      // wait till the array is populated
      filter((loaded) => loaded),
      // complete the observable
      take(1)
    );
  }

基本上,它等待 UserProfile[] 数组被填充。