Angular2处理http响应

我只是有一个关于构造和处理来自服务中的http请求的响应的问题。 我正在使用Angular2.alpha46 Typescript (刚开始testing它 – 我爱… Ps ..感谢所有的人一直在努力,并通过github贡献)

所以采取以下措施:

login-form.component.ts

import {Component, CORE_DIRECTIVES, FORM_DIRECTIVES} from 'angular2/angular2'; import {UserService} from '../../shared/service/user.service'; import {Router} from 'angular2/router'; import {User} from '../../model/user.model'; import {APP_ROUTES, Routes} from '../../core/route.config'; @Component({ selector: 'login-form', templateUrl: 'app/login/components/login-form.component.html', directives: [CORE_DIRECTIVES, FORM_DIRECTIVES] }) export class LoginFormComponent { user: User; submitted: Boolean = false; constructor(private userService:UserService, private router: Router) { this.user = new User(); } onLogin() { this.submitted = true; this.userService.login(this.user, () => this.router.navigate([Routes.home.as])) } } 

从这个组件我导入我的userService这将容纳我的http请求login用户的服务看起来像这样:

user.service.ts

 import {Inject} from 'angular2/angular2'; import {Http, HTTP_BINDINGS, Headers} from 'angular2/http'; import {ROUTER_BINDINGS} from 'angular2/router'; import {User} from '../../model/user.model'; export class UserService { private headers: Headers; constructor(@Inject(Http) private http:Http) { } login(user: User, done: Function) { var postData = "email=" + user.email + "&password=" + user.password; this.headers = new Headers(); this.headers.append('Content-Type', 'application/x-www-form-urlencoded'); this.http.post('/auth/local', postData, { headers: this.headers }) .map((res:any) => res.json()) .subscribe( data => this.saveJwt(data.id_token), err => this.logError(err), () => done() ); } saveJwt(jwt: string) { if(jwt) localStorage.setItem('id_token', jwt) } logError(err: any) { console.log(err); } } 

我想要做的是能够处理http请求后的调用返回的响应。 例如,如果用户凭证无效,我将从后端传回401响应。 我的问题是哪里是处理响应的最佳方式,并将结果返回给我调用该方法的组件,以便我可以操纵视图来显示成功消息或显示错误消息。

目前在我的服务login下,我目前没有处理的回应,我只是做一个callback回到原来的组件,但我觉得这不是正确的方式去呢? 有人可以阐明他们在这个典型的场景中会做什么吗? 我会处理订阅function的第一个参数中的响应:

  login(user: User, done: Function) { var postData = "email=" + user.email + "&password=" + user.password; this.headers = new Headers(); this.headers.append('Content-Type', 'application/x-www-form-urlencoded'); this.http.post('/auth/local', postData, { headers: this.headers }) .map((res:any) => res.json()) .subscribe( (data) => { // Handle response here let responseStat = this.handleResponse(data.header) // Do some stuff this.saveJwt(data.id_token); // do call back to original component and pass the response status done(responseStat); }, err => this.logError(err) ); } handleResponse(header) { if(header.status != 401) { return 'success' } return 'error blah blah' } 

在这种情况下是否可以回拨罚款,还是可以通过观察或承诺更好地处理?

总结我在问什么是…什么是最好的做法来处理来自http响应的响应,并处理从user.service.tsforms的视图状态回到login-form.component.ts

更新alpha 47

至于alpha 47,下面的答案(对于alpha46和以下)不再需要。 现在,Http模块自动处理返回的错误。 所以现在就像下面一样简单

 http .get('Some Url') .map(res => res.json()) .subscribe( (data) => this.data = data, (err) => this.error = err); // Reach here if fails 

阿尔法46及以下

您可以在subscribe之前处理map(...)的响应。

 http .get('Some Url') .map(res => { // If request fails, throw an Error that will be caught if(res.status < 200 || res.status >= 300) { throw new Error('This request has failed ' + res.status); } // If everything went fine, return the response else { return res.json(); } }) .subscribe( (data) => this.data = data, // Reach here if res.status >= 200 && <= 299 (err) => this.error = err); // Reach here if fails 

这里有一个简单的例子。

请注意,在下一个版本中,这是不必要的,因为所有低于200以上的状态码都会自动抛出一个错误,所以你不必自己检查它们。 检查此提交以获取更多信息。

在angular2 2.1.1我无法捕捉exception使用(数据),(错误)模式,所以我用.catch(…)实现它。

这很好,因为它可以与所有其他Observable链式方法(如.retry .map等)一起使用

 import {Observable} from 'rxjs/Rx'; Http .put(...) .catch(err => { notify('UI error handling'); return Observable.throw(err); // observable needs to be returned or exception raised }) .subscribe(data => ...) // handle success 

从文档 :

返回

(Observable):包含连续源序列元素的可观察序列,直到源序列成功终止。

服务 :

 import 'rxjs/add/operator/map'; import { Http } from '@angular/http'; import { Observable } from "rxjs/Rx" import { Injectable } from '@angular/core'; @Injectable() export class ItemService { private api = "your_api_url"; constructor(private http: Http) { } toSaveItem(item) { return new Promise((resolve, reject) => { this.http .post(this.api + '/items', { item: item }) .map(res => res.json()) // This catch is very powerfull, it can catch all errors .catch((err: Response) => { // The err.statusText is empty if server down (err.type === 3) console.log((err.statusText || "Can't join the server.")); // Really usefull. The app can't catch this in "(err)" closure reject((err.statusText || "Can't join the server.")); // This return is required to compile but unuseable in your app return Observable.throw(err); }) // The (err) => {} param on subscribe can't catch server down error so I keep only the catch .subscribe(data => { resolve(data) }) }) } } 

在应用程序中:

 this.itemService.toSaveItem(item).then( (res) => { console.log('success', res) }, (err) => { console.log('error', err) } )