繁体   English   中英

Angular 2 http变得可观察

[英]Angular 2 http get observable

我是来自jQuery背景的Angular 2的新手。 我正在努力处理简单的事情。

我的第一个任务是从为我提供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 //所有控制台日志都返回未定义

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"}]

将服务方法更改为:

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,其属性可以由接口定义。 如果要使用一个类,则需要使用新的Mail(.....)将每个POJO映射到该类的实例。

我建议使用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);
}

请参阅此处的官方教程。

这是您的问题:

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM