Angularルーターには、NgRxエフェクト内で使用する制限がありますか?
NgRxの学習を開始したばかりで、次のコードがあります。
@Effect() public authenticate$ = this.actions$
.ofType(authenticationActions.AUTHENTICATE)
.switchMap((action: AuthenticateAction) => this.authenticationService.authenticate(action.payload)
.map((data: TokenData) => {
const user: User = {
token: data.token,
username: 'dummy',
};
console.log(data);
this.router.navigateByUrl('/');
return new authenticationActions.AuthenticateSuccessAction(user);
})
.catch(error => { console.log(error); return Observable.throw(error); })
);
コンソールはデータ変数をログに記録し、AuthenticateSuccessAction
アクションがトリガーされているため、ルーター行は実行されていますが、ナビゲーションは行われていません。
@Effect() public authenticate$ = this.actions$.pipe(
ofType(authenticationActions.AUTHENTICATE),
map(action => action.payload),
exhaustMap((auth: any) =>
this.authenticationService.authenticate(auth)
.map((data: TokenData) => {
return user: User = {
token: data.token,
username: 'dummy',
};
}).catch(error => { console.log(error); return Observable.throw(error);
}).pipe(
map(user =>new authenticationActions.AuthenticateSuccessAction(user))
)
);)
@Effect({ dispatch: false })
loginSuccess$ = this.actions$.pipe(
ofType(authenticationActions.AuthenticateSuccessAction),
tap(() => this.router.navigate(['/']))
);
ExhaustMapを使用し、「AuthenticateSuccessAction」アクションをディスパッチするときに、リダイレクトのために別の効果を実行します。
個人的には、すべてのサービスをエフェクトから切り離したいのですが、ログイン成功後にcatchError()演算子を使用して、ログインに失敗した場合に別のアクションをディスパッチできます。
これがうまくいくことを願っています。 PS:私はこの答えを確認しませんでしたが、ロジックはこのようなものです。
リダイレクトのような別の効果を作成しないようにするアプローチが必要です。
this.actions$.pipe(
ofType(authenticationActions.AUTHENTICATE),
switchMap(action =>
this.authenticationService.authenticate(action.payload).pipe(
map(data => new authenticationActions.successAction(data)),
tap(() => this.router.navigate(['/'])),
catchError(error => new authenticationActions.failAction(error))
)
);
問題は、サービス呼び出しが失敗した場合、tap
が呼び出されないことです。失敗した場合、map
とtap
の両方がスキップされ、catchError
が優先されます。 。