web-dev-qa-db-ja.com

map()RxJSの代わりにtap()を使用し、Angular

ユーザーがログインしているかどうかを基本的にチェックするログインガードがあります。ログインしている場合は、ログインをスキップしてホームページに移動します。私はこのコードを書きました、そしてこれはうまくいきます:

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    return this.store.select(fromApp.isAuthenticated)
        .pipe(take(1),
            map(isAuthenticated => {
                if (isAuthenticated) {
                    this.router.navigate(['/home']);
                    return false;
                } else {
                    return true;
                }
            })
        )
}

さて、出力データ(isAuthenticated boolean)を変更または編集する必要がないので、私は考えました。まあ、なぜタップ演算子を使用しないのですか?だから、私は自分のコードを書き直します:

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    return this.store.select(fromApp.isAuthenticated)
        .pipe(take(1),
   HERE------> tap(isAuthenticated => {   <------ HERE
                if (isAuthenticated) {
                    this.router.navigate(['/home']);
                    return false;
                } else {
                    return true;
                }
            })
        )
}

それから私はChromeに行きました、そして、私は黒いページを見ました、そしてこれはそうでした:

いずれにしても、空白のページが表示されます。だから、私はデバッグに行きました、そして、それがif/elseブロックの中で正しくジャンプすることに気づきました...それで、なぜtap()がアプリを壊しているのですか?

4
panagulis72

これcanActivateの署名です:

interface CanActivate {
  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean
}

canActivatebooleanまたはPromiseを返す必要があります。したがって、それをmapしてbooleanまたはPromiseを返す必要があります。 tapはトリックを行いません。

6
siva636

Angularガードメカニズムが機能するには、ガードcanActivateが_Observable<boolean>_を返す必要があります。

mapを使用すると、isAuthenticatedから得られるものとは異なる戻り値を定義できます。これにより、表示される内容が説明されます。

最初のバージョンではcanActivateは実際に_Observable<boolean>_を返します-2番目の場合はこのthis.store.select(fromApp.isAuthenticated).pipe(take(1))を返しますが、おそらく望んでいるものではありません。

2
Picci