2016-02-13 54 views
8

我想要创建和分派HTTP操作的简单代码路径。我想要做的是一样的东西:Angular2 + ngrx/store用于处理失败的HTTP请求

this.http.request(...) 
    .map((res: Response) => res.json()) 
    .catch((err: any) => err.json()) 
    .map((payload: any) => { type: 'SUCCESS', payload }) 
    .catch((payload: any) => { type: 'FAILURE', payload}) 
    .subscribe((action: Action) => this.store.dispatch(action)); 

这样,无论是成功和失败的响应转换成JSON,然后基于成功/失败的标准分配正确的原型让这家店可以操作正确地。 (认为​​用户登录成功和失败,返回200或401)。

是否有更清洁或更好的处理方法?当前第二个.catch不能很好地发挥,因为它没有返回可观察的。

欢迎提出建议或其他解决方案吗?

回答

7

在我服务的一个我不喜欢这样写道:

get(url, actionType) { 
    this._http.get(BASE_URL + url) 
    .map(response => response.json()) 
    .map(payload => ({ type: actionType, payload })) 
    .subscribe(action => this.store.dispatch(action), error => this._apiErrorHandler(error)); 
} 

private _apiErrorHandler(response) { 
    let payload = response.json().error; 
    this.store.dispatch({ type: 'API_ERROR', payload }); 
} 
11

example-appngrx,针对这种情况,建议使用@Effects(检查文档文件夹),国际海事组织,是一个更清晰这样,检查服务:

@Injectable() 
export class AuthService { 
    private headers: Headers; 
    private API_ENDPOINT: string = "/api/user/"; 

    public constructor(
     private http: Http, 
     private localStorageService: LocalStorageService 
     ) { 
     this.headers = new Headers({ 'Accept': 'application/json' }); 
    } 

    public login(email: string, password: string): Observable<AuthUser> { 
     return this.http 
     .post(this.API_ENDPOINT + 'login', { 'email': email, 'password': password }, this.headers) 
     .map(res => res.json().data as AuthUser) 
     .catch(this.handleError); 
    } 

    private handleError(error: Response | any) { 
     let body = error.json(); 
     // .. may be other body transformations here 
     console.error(body); 
     return Observable.throw(body); 
    } 
} 

并检查效果:

@Injectable() 
export class AuthEffects { 

    constructor(
     private actions$: Actions, 
     private authService: AuthService, 
     private localStorageService: LocalStorageService 
    ) { } 

    @Effect() logIn$: Observable<Action> = this.actions$ 
     .ofType(auth.ActionTypes.LOGIN) 
     .map((action: Action) => action.payload as LoginCredentials) 
     .switchMap((credentials: LoginCredentials) => this.authService.login(credentials.email, credentials.password)) 
     .do((user: AuthUser) => this.localStorageService.setUser(user)) 
     .map((user: AuthUser) => new auth.LoginSuccessAction(user)) 
     .catch((error) => of(new auth.FlashErrors(error))); 

} 

关当然,你需要设置上的AppModule影响:

@NgModule({ 
imports: [ 
    StoreModule.provideStore(reducer), 
    EffectsModule.run(AuthEffects), 
    RouterStoreModule.connectRouter(), // optional but recommended :D 
], 
declarations: [...], 
providers: [AuthService, LocalStorageService, ...] 
}) 
export class AuthModule {} 

了解更多关于从回购的文档文件夹NGRX /效果。

+0

不会在连接错误时调用'new auth.LoginSuccessAction(user)'吗? – maurycy