@ngrx效果可防止switchmap在出错时中断

时间:2018-01-26 14:07:30

标签: angular typescript rxjs ngrx ngrx-effects

我在注册过程中有3个http呼叫:使用auth提供程序注册,在api中创建帐户,然后登录。

如果使用身份验证提供程序注册失败(例如帐户已存在),它仍会尝试在api中创建帐户。 如果我在@Effect的末尾添加一个catch,则第二次尝试(比如更正的凭据)将不再调用该效果。

如何阻止后续(accountSercice.CreateAccount和authenticationService.Login)switchMaps运行?

@Effect() AccountSigningUp$ = this.actions$
.ofType(ACCOUNT_SIGNING_UP)
.map((action: AccountActions.AccountSigningUp) => action.payload)
.switchMap(signUpModel => this.authenticationService.SignUp(signUpModel)
    .catch(err => {
        let signUpModel = new SignUpModel();
        signUpModel.message = err;
        return Observable.of(new AccountSignUpFailed(signUpModel))
    })
    .switchMap(signUpModel => this.accountService.CreateAccount((signUpModel as SignUpModel))
        .catch(err => {
            let signUpModel = new SignUpModel();
            signUpModel.message = err;
            return Observable.of(new AccountSignUpFailed(signUpModel))
        })
    )
    .switchMap(loginModel => this.authenticationService.Login((loginModel as LoginModel))
        .map(tokenModel => {
            this.tokenService.Save(tokenModel);
            return new AccountLoggedIn();
        })
        .catch(err => {
            let loginModel = new LoginModel();
            loginModel.message = err;
            return Observable.of(new AccountLoginFailed(loginModel))
        })
    )
    .map(() => new AccountCreated())
);

1 个答案:

答案 0 :(得分:3)

您可以为此方案创建三种不同的效果。并在第一次完成时调用另一种效果。像这样的东西 -

/**
* Effect For Auth service
*/
@Effect() authenticationService$ = this.actions$
.ofType(AUTH_SERVICE)
.map((action: AccountActions.AccountSigningUp) => action.payload)
.switchMap(signUpModel => this.authenticationService.SignUp(signUpModel)
.map(res =>({ type: action.CREATE_ACCOUNT, payload: res.json()}))
.catch(() => Observable.of({ type: action.AUTH_SERVICE_FAILED }))
)




/**
    * Effect For Create Account service
    */
    @Effect() authenticationService$ = this.actions$
    .ofType(CREATE_ACCOUNT)
    .map((action: AccountActions.AccountSigningUp) => action.payload)
    .switchMap(signUpModel => this.accountService.CreateAccount((signUpModel as SignUpModel))
    .map(res =>({ type: action.LOGIN, payload: res.json()}))
    .catch(() => Observable.of({ type: action.CREATE_ACCOUNT_FAILED }))
    )

    /**
    * Effect For Login service
    */
    @Effect() authenticationService$ = this.actions$
    .ofType(LOGIN)
    .map((action: AccountActions.AccountSigningUp) => action.payload)
    .switchMap(signUpModel => this.authenticationService.Login((loginModel as LoginModel))
    .map(res =>({ type: action.LOGIN_SUCCESS, payload: res.json()}))
    .catch(() => Observable.of({ type: action.LOGIN_FAILED }))
    )

in case若要在成功调用中调用两个动作,可以像这样使用mergeMap。

@Effect() authenticationService$ = this.actions$
.ofType(LOGIN)
.map((action: AccountActions.AccountSigningUp) => action.payload)
.switchMap(signUpModel => this.authenticationService.Login((loginModel 
 as LoginModel))
.mergeMap((response) =>            
 return[
     ({ type: action.FIRST_ACTION, payload: response.json() }),
     ({ type: action.SECOND_ACTION, payload: response.json()})
      ];
 });