Эффект «AuthEffects.authLogin $» отправил недопустимое действие: не определено - PullRequest
0 голосов
/ 04 июля 2018

В приложении 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();
            }));
}),

Итак, я смотрю на это поведение: после того, как пользователь вошел в систему, я сохраняю токен, я (в конце концов) перенаправляю на нужную страницу, а затем удаляю эту страницу из State. Я уверен, что первый mergeMap () работает .. все было сломано, когда я добавил последний кусок (выхлопная карта), и я не могу найти решение для ошибки консоли:

ОШИБКА Ошибка: эффект «AuthEffects.authLogin $» отправил недопустимое действие: undefined

Если я изменю позицию последнего «возврата»:

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
        }));

У меня ошибка компиляции на выхлопе ():

Аргумент типа '() => void' нельзя назначить параметру типа '(значение: {тип: строка; полезная нагрузка ?: undefined;} | {тип: строка; полезная нагрузка: любая;}, индекс: число ) ... Тип 'void' нельзя назначить типу 'ObservableInput <{}>'

1 Ответ

0 голосов
/ 05 октября 2018

Использование Угловой 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)))
      )
    )
  );
...