【问题标题】:Angular2 Promise : How to use the response from Http GetAngular2 Promise:如何使用来自 Http Get 的响应
【发布时间】:2017-07-05 03:38:24
【问题描述】:

我是 Angular 新手,关注 this tutorial 学习基础知识。考虑以下 http get 调用。

getHeroes(): Promise<Hero[]> {
    return this.http.get(this.heroesUrl)
               .toPromise()
               .then(response => response.json().data as Hero[])
               .catch(this.handleError);
  }

在将 observable 转换为 Promise 后,如何使用 then() 子句中的函数真正利用响应(例如控制台日志、解析和访问响应元素等)?

我尝试了以下操作,即使它记录了响应,我也无法真正访问响应对象中的任何内容。

this.http.get(url, {headers : this.headers})
                        .toPromise()
                        .then(function(res) {
                                console.log(res);
                                return res => res.json().data as Query[];
                        })
                        .catch(this.handleError);

任何帮助将不胜感激。谢谢。

【问题讨论】:

  • 您需要从响应中访问什么,您能否更详细地描述它。我建议使用 Observables 而不是 Promise。 Observables 可以被取消等。看看这篇文章然后决定:stackoverflow.com/questions/37364973/…
  • 谢谢。假设这调用了一个返回用户对象的 Web 服务,我想从响应中获取名称。
  • 您在response 中得到了什么,您可以将其粘贴到问题中吗?

标签: javascript http angular promise


【解决方案1】:

这里有一个例子来说明如何做到这一点。

没有必要,但提供了一个很好的代码结构创建一个处理所有用户请求的服务:

用户服务

@Injectable()
export class UserService {

   constructor(private http: Http) { }

   getById(id: string): Observable<User> {
      return this.http.get("http://127.0.0.1" + '/api/CustomUsers/' + id)
      // ...and calling .json() on the response to return data
      .map((res: Response) => {
         var user = User.withJSON(res.json());
         return user;
      })
      //...errors if any
      .catch((error: any) => Observable.throw(error));
   }
}

所以这里我们获取具有给定 id 的用户,并使用返回的 json 创建一个用户对象。

用户模型

export class User {

    constructor(public id: string, public username: string, public email: string) {

    }

    static withJSON(json: any): User {

        // integrity check
        if (!json || !json.id || !json.username || !json.email) { return undefined; }

       var id = json.id;
       var username = json.username;
       var email = json.email;

       // create user object
       var user = new User(id, username, email);
       user.firstname = firstname;

       return user;
   }

服务电话

this.userService.getById(this.id).subscribe(user => {
    this.user = user;
  },
    err => {
       console.error(err);
    });

希望对你有帮助

【讨论】:

    【解决方案2】:

    Angular2 使用 RXjs 可观察而不是承诺。它的工作原理如下。

    如下创建httpService。

    httpService.ts

    import {Injectable, Inject} from '@angular/core';
    import {Http, Response, RequestOptions, Request, Headers} from '@angular/http';
    
    declare let ApiUrl : any;
    
    @Injectable()
    export class httpService {
        constructor(private http: Http){}
    
        getHeader = () => {
            let headers = new Headers();
            headers.append("Content-Type", 'application/json');
    
            return headers;
        };
    
        request = (req) => {
            let baseUrl = ApiUrl,
                requestOptions = new RequestOptions({
                method: req.method,
                url: baseUrl+req.url,
                headers: req.header ? req.header : this.getHeader(),
                body: JSON.stringify(req.params)
            });
    
            return this.http.request(new Request(requestOptions))
                            .map((res:Response) => res.json());
        }
    }
    

    现在只需在您的组件/指令中使用此服务,如下所示:

    componenet.ts

    import {Component, Inject, Directive, Input, ElementRef} from '@angular/core';
    
    @Directive({
      selector: '[charts]' // my directive name is charts
    })
    export class chartsDirective{
    
      constructor(@Inject('httpService') private httpService){}
    
      ngOnInit(){
    
        this.httpService.request({method: 'POST', url: '/browsers', params:params, headers: headers})
                .subscribe(
                    data => self.data = data, //success
                    error => console.log('error', error),
                    () => {console.log('call finished')}
                )
      }
    }
    

    最后,您只需要将 httpService 添加到 ngModule 的提供者:

    appModule.ts

    import {NgModule} from '@angular/core';
    import {ApiService} from "./api.service";
    
    @NgModule({
        providers: [
            {provide : 'httpService', useClass : httpService}
        ]
    })
    
    export class apiModule{}
    

    现在,您可以像在 component.ts 中那样通过注入在代码中的任何位置使用 httpService

    【讨论】:

    • http.get() 返回一个 Observable,但他使用 rxjs toPromise() 函数将其转换为 Promise。这在 Angular2 中完全没问题,因此绝对不需要重构他的所有代码。
    • @NicoVanBelle 是的,我明白了,重写的原因是让他了解如何通过最佳实践来实现它。
    • @Xin 他试图将 observable 转换为不需要的 promise。 Observable 只是一种承诺。除此之外,代码是结构化和模块化的。如果您认为我可以在我的答案中更新更多内容,请告诉我。
    • @jigargala observables 在 HTTP 请求的上下文中没有语义意义。请求是有开始也有结束的东西。 Observables 是持续的数据流。所以不,在这里使用 observables 不是最佳实践。
    • 同意,程序员可以选择编写干净而有意义的代码,也可以可能使用数十种功能。
    【解决方案3】:

    我遇到了类似的问题。调试响应对象后,我发现 res.json() 对象上不存在数据。改为:

    this.http.get(url, {headers : this.headers})
                        .toPromise()
                        .then(function(res) {
                                console.log(res);
                                return res => res.json() as Query[];
                        })
                        .catch(this.handleError);
    

    请注意,我所做的只是更改了 return res =&gt; res.json().data as Query[]; 的行

    return res =&gt; res.json() as Query[];

    【讨论】:

      猜你喜欢
      • 2012-04-28
      • 1970-01-01
      • 2015-07-01
      • 2017-05-25
      • 1970-01-01
      • 2020-05-21
      • 1970-01-01
      • 2018-07-13
      • 1970-01-01
      相关资源
      最近更新 更多