错误后rx被破坏时可观察到 [英] Observable with rx broken after error

查看:76
本文介绍了错误后rx被破坏时可观察到的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用ngrx store + ng效果为我的应用编写登录流程。我已经设法编写它并且它在快乐的场景中工作,但是当用户向表单输入错误的值,以便服务器响应401时,下一次登录尝试没有效果。我已经读过,在使用observable时必须捕获异常,以便不破坏流,但据我所知,我已经捕获了异常并且现在仍在工作。

Im trying to write login flow for my app using ngrx store + ng effects. I have managed to write it and it works in happy scenerio, but when user inputs wrong values to the form, so that server responds with 401, the next login attempt has no effects. I have read that the exception must be catch when working with observables in order not to 'break' the stream, but as far i know I'm catch the exception and still its now working.

在代码下方;

export class LoginComponent {

  logged = new Observable<any>();

  constructor(private store: Store<AppStore>) {
   this.logged = store.select('login');
  }

  login(username: string, password: string){
    let body = JSON.stringify({username, password});
    this.store.dispatch({type: LoginActions.ATTEMPT_LOGIN, payload: body});
  }

}

@Injectable()
export class LoginEffects {

  constructor(
    private actions: Actions,
    private loginService: LoginService
  ) { }

  @Effect() login = this.actions
    .ofType(LoginActions.ATTEMPT_LOGIN)
    .map(toPayload)
    .switchMap(payload => this.loginService.attemptLogin(payload))
    .map(response => new LoginActions.LoginSuccess(response))
    .catch(error => of(new LoginActions.LoginFailed(error)));

  @Effect() success = this.actions
    .ofType(LoginActions.LOGIN_SUCCESS)
    .map(toPayload)
    .map(payload => localStorage.setItem(Global.TOKEN, payload))
    .map(() => go(['/menu']));

  @Effect() error = this.actions
    .ofType(LoginActions.LOGIN_FAILED)
    .map(toPayload)
    .map(payload => console.log(payload))
    .ignoreElements();
}

export const login = (state: any = null, action: Actions) => {
  switch (action.type) {
    case LoginActions.ATTEMPT_LOGIN:
      console.log('hello from reducer attempt login');
      return action.payload;
    case LoginActions.LOGIN_SUCCESS:
      console.log('hello from reducer success login');
      return action.payload;
    case LoginActions.LOGIN_FAILED:
      console.log('hello from reducer failed login');
      return action.payload;
    default:
      return state;
  }
};

@Injectable()
export class LoginService {

  auth = new Observable<any>();
  constructor(private store: Store<AppStore>, private http: Http) {
    this.auth = store.select('auth');
  }

  attemptLogin(payload): Observable<any> {
    // let body = JSON.stringify({username, password});
    return this.http.post(Global.API_URL + '/login', payload)
      .map(response => response.headers.get('Authorization'));
      // .map(action => (
      //   { type: LoginActions.ATTEMPT_LOGIN, payload: action}))
      // .subscribe(action => {this.store.dispatch(action);
      // });
  }
}


推荐答案

捕获错误, catch 返回的observable用于继续链。返回的observable完成,完成效果并看到 ngrx 取消订阅效果。

When an error is caught, the observable returned by catch is used to continue the chain. And the returned observable completes, which completes the effect and sees ngrx unsubscribe from the effect.

移动 map catch 进入 switchMap

@Effect() login = this.actions
.ofType(LoginActions.ATTEMPT_LOGIN)
.map(toPayload)
.switchMap(payload => this.loginService.attemptLogin(payload)
  .map(response => new LoginActions.LoginSuccess(response))
  .catch(error => of(new LoginActions.LoginFailed(error)))
);

捕获 switchMap 将无法完成效果。

这篇关于错误后rx被破坏时可观察到的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆