Действие Ngrx не завершается после выполнения ошибки - PullRequest
0 голосов
/ 29 августа 2018

Действие не завершается правильно после возникновения ошибки

В моем приложении я создал действие по удалению пользователя, однако перед удалением этого пользователя на экране появляется сообщение Dialog с просьбой сообщить пароль администратора, если пароль администратора правильный, то он удаляет пользователя.

Моя проблема в том, что когда пароль администратора неверен, я вызываю действие, чтобы сказать, что введенный пароль недействителен, и после этого момента я больше не могу завершить действие, введя действительный пароль.

Последовательность акций:

[Пользователь] удалить пользователя;

[Auth] повторно аутентифицировать пользователя;

[Auth] ошибка повторной аутентификации (неверный пароль);

[Auth] повторно аутентифицировать пользователя

[Auth] повторно аутентифицировать пользователя

[Auth] повторно аутентифицировать пользователя

НЕТ УСПЕХА И НЕТ ОШИБКИ

Проблема: После этого, когда я пытаюсь снова вызвать действие повторной аутентификации с действительным паролем, вызывается только функция Reauthenticate, но не обнаружено, что это действие успешно выполнено.

Я видел в некоторых источниках информацию об использовании Ngrx , которая, в некотором смысле, создает @Effect для прослушивания вызова действия, после того, как вызов сделан и произошла ошибка, это действие больше не может быть вызван снова, возвращая успех.

Может ли это быть правдой?

usuarios.effects.ts:

@Effect()
deleteUser$: Observable<Action> = this._action$.ofType(userActions.DELETE)
    .map((action: userActions.Delete) => action)
    .switchMap(data => {
        return this._userService.deleteUser(data.payload);
    })
    .map(() => new userActions.DeleteSuccess())
    .catch((err) => {
        return Observable.of(new userActions.DeleteError({error: err}));
    });

usuarios.service.ts:

deleteUser(user: IUser): Observable<void> {

    const reautenticateUser = this._modalService.create({
        nzTitle: 'Delete user',
        nzContent: ReauthenticateUserComponent,
        nzFooter: [{
            type: 'danger',
            label: 'Cancel',
            onClick: (componentInstance) => {
                componentInstance.closeDialog();
            }
        },
        {
            type: 'primary',
            label: 'Ok',
            onClick: (componentInstance) => {
                componentInstance.reauthenticateUser();
            },
            disabled: (componentInstance) => {
                return componentInstance.adminPassword.invalid;
            },
        }
        ]
    });

    return reautenticateUser.afterClose
        .switchMap((authenticated: boolean) => {

            if (authenticated) {
                const ref = this._angularFirestore
                    .doc<IProfissional | IRecepcionista>(`users/${usuario.id}`);

                return Observable.fromPromise(ref.delete()).map(() => {
                    this._message.info('User deleted success', {
                        nzDuration: 5000,
                        nzPauseOnHover: true,
                        nzAnimate: true
                    });
                });
            }

            throw new Error('Password invalid');
        });
}

ПРИМЕЧАНИЕ: Когда действие по удалению пользователя завершено успешно, я могу выполнить действие снова без проблем.

Запуск в последовательности ниже, у меня нет проблем:

[Пользователь] удалить пользователя;

[Auth] повторно аутентифицировать пользователя;

[Аутентификация] повторная аутентификация (пароль действителен);

[Пользователь] удалить пользователя;

[Пользователь] удалить пользователя;

[Auth] повторно аутентифицировать пользователя;

[Аутентификация] повторная аутентификация (пароль действителен);

ПРОДОЛЖЕНИЕ ...

Ответы [ 2 ]

0 голосов
/ 24 июля 2019

когда я вернул err, я получил сообщение ниже, и ничего больше не работало после этого:

ERROR Error: Detected unserializable action at "error"

Мне удалось решить, вернув err.message вместо err.

mergeMap(data =>
  this._userService.deleteUser(data.payload).pipe(
    map(() => new userActions.DeleteSuccess()),
    catchError((err) =>
      of(new userActions.DeleteError({error: err.message}))
    }),
  )
)
0 голосов
/ 29 августа 2018

Это потому, что Observable завершает свою работу, когда обнаруживает ошибку. Вы должны отловить ошибку внутри, чтобы внешний Observable продолжал излучать:

.mergeMap(data =>
    this._userService.deleteUser(data.payload)
    .map(() => new userActions.DeleteSuccess())
    .catch((err) =>
        Observable.of(new userActions.DeleteError({error: err}))
    )        
)

Я переключился на mergeMap Вы, вероятно, не хотите отменять действие удаления другим действием удаления. Также, если вы хотите использовать RxJS 6:

mergeMap(data =>
    this._userService.deleteUser(data.payload).pipe(
        map(() => new userActions.DeleteSuccess()),
        catchError((err) =>
          of(new userActions.DeleteError({error: err}))
        }),
    )
)
...