问题描述
我正在尝试使用 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
内部捕获不会完成效果.
Catching inside the switchMap
won't complete the effect.
这篇关于错误后 rx 损坏时可观察到的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
更多推荐
[db:关键词]
发布评论