【问题标题】:Angular 2 http get observableAngular 2 http 可以观察到
【发布时间】:2017-06-24 14:26:14
【问题描述】:

我是 Angular 2 的新手,来自 Jquery 背景。我正在为简单的事情而苦苦挣扎。

我的第一个任务是从为我提供 JSON 服务的 API 填充 HTML 表。

问题是在我尝试创建 html 之前,我试图从 json 填充邮件类对象数组,但它一直返回未定义。我已经签入了提琴手,并且正在提供 json。

我已经创建了:

  • get-mail.service.ts 下载 json
  • inbboxmail.component.html|ts|css 成为视图
  • mail.ts 成为我的模型

get-mail.service.ts - 这里 .map 函数控制台日志与整个 json 一起返回(如我所料),但 .do 控制台日志未定义

import { Injectable, Inject } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Observable } from 'rxjs';
import { Mail } from "../model/mail"   // My Model

import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';

@Injectable()
export class GetMailService {

    constructor(private http: Http, @Inject('ORIGIN_URL') private originUrl: string) {}

  getMail(): Observable<Mail[]> {
      return this.http.get(this.originUrl + '/api/mail/')
          // ...and calling .json() on the response to return data
          .map((res: Response) => { res.json(); console.log("map", res.json()); })  //This is coming back with my entire json
          .do(data => console.log("all:" + JSON.stringify(data))) //all: undefined
          //...errors if any
          .catch((error:any) => Observable.throw(error.json().error || 'Server error'));
  }

}

inboxmail.component.ts //所有控制台日志都返回 undefined

import { Component, Inject } from '@angular/core';
import { GetMailService } from '../../../services/get-mail.service';
import { Observable } from 'rxjs';
import { Mail } from '../../../model/mail'

@Component({
    selector: 'inboxmail',
    templateUrl: './inboxmail.component.html',
    styleUrls: ['./inboxmail.component.css'],
    providers: [GetMailService]

})
export class InboxMailComponent {
    public mail: Mail[];

    constructor(private service: GetMailService) {
        service.getMail()
            .subscribe(_mail => { console.log("mail", _mail); this.mail = _mail },  
                 null,
                 () => console.log("complete", this.mail));
    }

}

邮件模型

export class Mail {
    constructor(
        public reference: string,
        public ocrText: string,
        public status: string,
        public create: Date
    ) { }
}

提供的 json(为示例目的而缩短)

[{"reference":"1897","ocrText":"magna adipiscing euismod euismod elit . ","status":"Stored","created":"2017-07-04T14:09:25.2565869Z"},{"reference":"1897","ocrText":"magna adipiscing euismod euismod elit . ","status":"Stored","created":"2017-07-04T14:09:25.2565869Z"}]

【问题讨论】:

    标签: angular angular2-services angular2-http


    【解决方案1】:

    将服务方式改为:

    getMail(): Observable<Mail[]> {
        /*return this.http.request('./data/people.json')
            .map(res => res.json());*/
          return this.http.get(this.originUrl + '/api/mail/')
              // ...and calling .json() on the response to return data
              .map((res: Response) => { console.log("map", res.json());return res.json(); })  //This is coming back with my entire json
              .do(data => console.log("all:" + JSON.stringify(data))) //all: undefined
              //...errors if any
              .catch((error:any) => Observable.throw(error.json().error || 'Server error'));
      }
    

    并将数据模型的定义更改为接口,如下所示:

    export interface Mail {
        reference: string;
        ocrText: string;
        status: string;
        create: Date;
    }
    

    为什么是接口?好吧,您的服务正在返回一个 JSON 格式的字符串,该字符串可以映射到 POJO,其属性可以由接口定义。如果要使用类,则需要使用 new Mail(.....) 将每个 POJO 映射到该类的实例。

    【讨论】:

      【解决方案2】:

      我建议使用toPromise 运算符将Observable 转换为Promise,因为Promise 可能比Observable 更容易理解。

      import 'rxjs/add/operator/toPromise';
      getHero(id: number): Promise<Hero> {
        const url = `${this.heroesUrl}/${id}`;
        return this.http.get(url)
          .toPromise()
          .then(response => response.json().data as Hero)
          .catch(this.handleError);
      }
      

      见官方教程here

      【讨论】:

        【解决方案3】:

        这是你的问题:

        .map((res: Response) => { res.json(); console.log("map", res.json()); })
        

        当您调用 res.json() 时,它会返回 JSON 对象,但您实际上并未将其转发到流中的下一步(do())。将该行更改为

        .map((res: Response) => res.json())
        

        现在您正在返回 JSON 对象,该对象将作为do() 的输入提供,并将在您的Subscription 中发出

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-06-11
          • 2017-05-12
          • 1970-01-01
          • 2017-04-06
          • 2016-06-04
          • 1970-01-01
          相关资源
          最近更新 更多