2017-02-16 13 views
2

Я новичок в Angular и следую this tutorial, чтобы узнать основы. Рассмотрим следующий http get call.Angular2 Promise: Как использовать ответ от Http Get

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

После преобразования наблюдаемого на обещание, как я могу реально использовать ответ (например, лог консоли, разобрать и получить доступ к элементу ответа .. и т.д.) с помощью функции внутри то() п?

Я пробовал следующее, даже если он регистрирует ответ, я не могу получить доступ к чему-либо в объекте ответа.

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

Любая помощь будет очень признательна. Спасибо.

+1

Что делать вы needto доступ из ответа вы могли бы описать его более подробно. И я бы предложил использовать Observables вместо обещаний. Наблюдаемые могут быть отменены и т. Д. Взгляните на этот пост и решите тогда: http://stackoverflow.com/questions/37364973/angular-2-promise-vs-observable –

+0

спасибо. допустим, это вызывает веб-службу, которая возвращает объект User, и я хочу получить имя из ответа. – Maddy

+0

Что вы получили в ответ? Можете ли вы вставить это в вопрос? – Sravan

ответ

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

И, наконец, вы justt нужно добавить свой httpService к провайдеру ngModule:

appModule.ts

import {NgModule} from '@angular/core'; 
import {ApiService} from "./api.service"; 

@NgModule({ 
    providers: [ 
     {provide : 'httpService', useClass : httpService} 
    ] 
}) 

export class apiModule{} 

Теперь Вы можете использовать HTTPService в любом месте вашего кода, вводя, как мы это делали в component.ts

+2

'http.get()' возвращает Observable, но он преобразует его в Promise, используя функцию rxjs 'toPromise()' funtion. Это абсолютно нормально в Angular2, поэтому абсолютно не нужно реорганизовывать весь его код. –

+0

@NicoVanBelle Да, я понял, что причина переписывания заключалась в том, чтобы заставить его понять, как это можно реализовать с помощью лучших практик. –

+0

@jigargala не могли бы вы объяснить, почему ваш код лучше всего подходит для него? – Xin

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

Так вот мы забираем пользователю с данным идентификатором и создает пользовательский объект с возвращенным 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); 
    }); 

Надеется, что это помогает

0

У меня была аналогичная проблема. После отладки объекта ответа я обнаружил, что данных не было в объекте 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 => res.json().data as Query[];

к return res => res.json() as Query[];