2017-08-05 1 views
3

Je suis en train d'essayer d'écrire un flux de connexion pour mon application en utilisant les effets ngrx store + ng. J'ai réussi à l'écrire et cela fonctionne dans le scénario heureux, mais lorsque l'utilisateur entre des valeurs incorrectes dans le formulaire, de sorte que le serveur répond avec 401, la prochaine tentative de connexion n'a aucun effet. J'ai lu que l'exception doit être attraper lorsque vous travaillez avec des observables afin de ne pas «casser» le flux, mais pour autant que je sache, je suis attraper l'exception et toujours son travail maintenant.Observable avec rx brisé après erreur

en dessous du code;

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); 
     // }); 
    } 
} 
+0

importez-vous tous? – Aravind

Répondre

3

Lorsqu'une erreur est prise, l'observable renvoyée par catch est utilisé pour continuer la chaîne. Et l'observable retourné se termine, ce qui termine l'effet et voit ngrx se désinscrire de l'effet.

Déplacer le map et catch dans le 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))) 
); 

Attraper l'intérieur de la switchMap ne termine pas l'effet.