Typescript Angular2处理http响应

Typescript Angular2处理http响应,typescript,angular,Typescript,Angular,我只是有一个关于服务中http请求的结构和处理响应的问题。我正在使用Angular2.alpha46打字脚本(刚刚开始测试-我喜欢它…Ps…。感谢所有一直致力于此并通过github作出贡献的人) 因此,采取以下措施: 登录表单.component.ts import {Component, CORE_DIRECTIVES, FORM_DIRECTIVES} from 'angular2/angular2'; import {UserService} from '../../shared/serv

我只是有一个关于服务中http请求的结构和处理响应的问题。我正在使用Angular2.alpha46打字脚本(刚刚开始测试-我喜欢它…Ps…。感谢所有一直致力于此并通过github作出贡献的人)

因此,采取以下措施:

登录表单.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]))
    }
}
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);
    }
}
从这个组件中,我导入了我的userService,它将容纳我的http请求以登录用户。该服务如下所示:

user.service.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]))
    }
}
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响应。我的问题是,处理响应并将结果返回到调用方法的组件的最佳方法是什么,这样我就可以操纵视图来显示成功消息或显示错误消息

目前,在我的服务登录下,我目前没有处理响应,我只是回拨到原始组件,但我觉得这不是正确的方法?有人能解释一下在这种典型情况下他们会做什么吗?我是否会在subscribe函数的第一个参数中处理响应,如下所示:

 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.ts返回到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]))
    }
}
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);
    }
}
从alpha 47开始,不再需要以下答案(对于alpha 46及以下版本)。现在Http模块自动处理返回的错误。因此,现在的问题很简单,如下所示

http
.get('某个Url')
.map(res=>res.json())
.订阅(
(data)=>this.data=data,
(err)=>this.error=err);//如果失败,请到达这里
阿尔法46及以下

您可以在
订阅之前在
映射(…)
中处理响应

http
.get('某个Url')
.map(res=>{
//如果请求失败,抛出一个将被捕获的错误
如果(分辨率状态<200 | |分辨率状态>=300){
抛出新错误(“此请求已失败”+res.status);
} 
//如果一切顺利,请回复
否则{
返回res.json();
}
})
.订阅(
(data)=>this.data=data,//如果res.status>=200&&this.error=err,则到达此处;//如果失败,请到达这里
下面是一个简单的例子


请注意,在下一版本中,这是不必要的,因为所有低于200和高于299的状态代码都会自动抛出错误,因此您不必自己检查它们。查看此项了解更多信息。

在angular2.1.1中,我无法使用(数据),(错误)模式捕获异常,因此我使用.catch(…)实现它

这很好,因为它可以与所有其他可观察的链式方法一起使用,如.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
发件人:

返回

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

服务:

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) }
)

在下一版本中(请参阅)
Http
将在您获得非200状态代码时出错。现在,您可以在
map()
中处理响应,检查那里的状态并抛出错误或传递值。感谢您的快速回复。酷!我想,我知道有些事情仍然有待讨论。。。所以我想确认一下。。。您认为现在完全可以在map中处理响应状态并在回调中传递值吗?你能不能用更好的方式,或者回电话就足够了?你根本不需要回电话,看到我的答案,它将有望回答您的问题:DAwesome我完全理解commit and plunker如何处理标头状态,但我只是想知道,将错误或成功数据传回我调用该方法的原始组件的最佳方法是什么,以便我可以将其分配给变量并将其绑定到看法您的示例非常棒,但是您正在对该组件调用http请求,这样您就可以在同一组件中分配错误或成功数据,因为它的上下文是共享的;但是我如何处理服务中的响应,然后当我完成传递响应和代码逻辑以成功或失败时,我会将该逻辑移出服务。在服务中,我只需返回http.post().map(/*handle result*/)
,然后在我的组件中,我将执行
此.userService.login(…).subscribe(/*handle data*/)
您链接的plnkr工作不正常请修复它。我需要在REST API运行时获取状态代码。我如何获取此代码?@PardeepJain你说不工作是什么意思?如果您想使请求失败,只需注释掉第一个
get
,并取消对第二个的注释。如果我想同时返回res.status和res.json(),该怎么办?
在angular2 v2.1.1上返回{status:res.status,json:res.json()}
im,并且该方法不会在服务器启动时触发错误部分。我看到zone.js在控制台中写出了异常。我确实需要截取它,以便在UIQ问题中提供一些反馈:可观察到的东西是否可以是其他非错误的东西?否则,如果我再次重复错误,有什么意义?不确定你的意思。可观察的不是错误。通常,它将携带可以订阅的数据对象。如果发生错误,它将触发catch块。在这种情况下,必须进行投掷,以便链可以继续。如何处理这一问题取决于其他用户。例如,您可以订阅此结果