效果“ AuthEffects.authLogin $”调度了无效的操作:未定义

时间:2018-07-04 15:06:26

标签: angular redux rxjs observable side-effects

在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 <{}>”

1 个答案:

答案 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)))
      )
    )
  );