在Angular 6(和RxJS)应用程序中,我具有一个管理登录的效果。它首先调用服务器,然后设置和解码令牌。最后,我添加了处理重定向的最后一个操作。
是这种情况: 用户(未登录)尝试访问“个人资料”页面。在AuthGuard中,我拦截了它,然后保存了所需的页面(auth-guard.service.ts):
.. Here I already know that the user is not authenticated.
let url = state.url;
if (url) {
.. I save in the Store the url
this.store.dispatch(new CoreActions.SaveRedirectUrl(url));
}
this.router.navigate(['/login']);
return false;
这是Auth效果的最后两部分( auth.effects.ts ,在我分派操作 DO_LOGIN 时调用):
, mergeMap((tokenObj: any) => {
return [
{
type: AuthActions.LOGIN
},
{
type: AuthActions.SET_TOKEN,
payload: tokenObj.token
},
{
type: ProfileActions.DECODE_TOKEN,
payload: tokenObj.token
}
];
})
, exhaustMap(() => {
return this.store.select('core')
.pipe(
map(coreState => {
if (coreState.redirectUrl) {
this.router.navigate([coreState.redirectUrl]);
} else {
this.router.navigate(['/']);
}
new CoreActions.RemoveRedirectUrl();
}));
}),
因此,我正在查看此行为:用户登录后,我保存了令牌,我(最终)重定向到所需的页面,然后从该州中删除该页面。我确定第一个mergeMap()可以工作..当我添加最后一个(exhaustMap)时,一切都坏了,并且找不到控制台错误的解决方案:
错误错误:效果“ AuthEffects.authLogin $”调度了无效的操作:未定义
如果我更改了最后一个“返回”的位置:
this.store.select('core') -----> from here
.pipe(
map(coreState => {
if (coreState.redirectUrl) {
this.router.navigate([coreState.redirectUrl]);
} else {
this.router.navigate(['/']);
}
return new CoreActions.RemoveRedirectUrl(); -----> to here
}));
ExhaustMap()出现编译错误:
类型'()=>无效'的参数不能分配给类型'(值:{类型:字符串;有效载荷?:未定义;} | {类型:字符串;有效载荷:任何;},索引:数字)...'。 类型“ void”不能分配给类型“ ObservableInput <{}>”
答案 0 :(得分:0)
使用 Angular 6 和rxjs 6.0.0
:
最近,我在管理ngrx
登录名时遇到了类似的问题,并且遵循与您在上面描述的相似的模式。出于$login
的作用,我最初有:
@Effect()
login$ = this.actions$.pipe(
ofType<Login>(AuthActionTypes.Login),
map(action => action.payload),
exhaustMap((auth: Authenticate) =>
this.authService.loginWithUsernameAndPassword(auth).pipe(
map(user => {
if (user && user.token) {
this.cookieService.set('token', user.token)
}
new LoginSuccess({user})
return user;
}),
catchError(error => of(new LoginFailure(error)))
)
)
);
我返回了user
,这给了我一个错误,因此我删除了该错误并尝试创建new LoginSuccess({user})
。但是,那也给了我一个类似于您上面描述的错误的错误。我发现map()
内部的pipe()
函数不需要副作用。我只是通过使用tap()
来创建使用cookieService
的“副作用”来解决问题,因为tap()
返回的对象相同。完成此操作后,一切都会按预期进行-没有错误或异常。
@Effect()
login$ = this.actions$.pipe(
ofType<Login>(AuthActionTypes.Login),
map(action => action.payload),
exhaustMap((auth: Authenticate) =>
this.authService.loginWithUsernameAndPassword(auth).pipe(
// user tap to set my cookie and achieve my side effect
tap(user => {
if (user && user.token) {
this.cookieService.set('token', user.token)
}
}),
// use map without any side effect
map(user => new LoginSuccess({ user })),
catchError(error => of(new LoginFailure(error)))
)
)
);