Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/32.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Json 使用角度观察者通过网络获取数据_Json_Angular_Rxjs_Angular2 Http - Fatal编程技术网

Json 使用角度观察者通过网络获取数据

Json 使用角度观察者通过网络获取数据,json,angular,rxjs,angular2-http,Json,Angular,Rxjs,Angular2 Http,我正在开发一个Angular应用程序,其中包含用户可以添加的(金融)交易列表。这一切进展顺利,我正在尝试从服务提供的静态列表切换到尝试从本地Node.js服务器获取数据。我正在使用观察者异步获取交易列表 我一直在关注Angular的和相关的。然而,尽管我可以看到来自服务器的数据,但我在使用.subscribe()方法从中获取有用的数据集时遇到了问题 这是我连接到节点服务器的服务: @Injectable() export class TradeService { private url

我正在开发一个Angular应用程序,其中包含用户可以添加的(金融)交易列表。这一切进展顺利,我正在尝试从服务提供的静态列表切换到尝试从本地Node.js服务器获取数据。我正在使用观察者异步获取交易列表

我一直在关注Angular的和相关的。然而,尽管我可以看到来自服务器的数据,但我在使用.subscribe()方法从中获取有用的数据集时遇到了问题

这是我连接到节点服务器的服务:

   @Injectable()
export class TradeService {
  private url = '...';  // URL to web API
  tradeArray: Trade[] = [];
  constructor(private http: Http) { }
  //-----------GETTERS---------------//
  getTradeObservable(): Observable<Trade> {
    return this.http.get(this.url)
      .map(this.extractData)
      .catch(this.handleError);
  }

  private extractData(res: Response) {
    let body = res.json();
    console.log("body:" + body);
    console.log("Entire Body.trades: " + body.trades);
    return body.trades;
  }

  getTrades(): any {
    this.getTradeObservable()
      .subscribe(
          trade => this.tradeArray.push(trade));
    return this.tradeArray;
  }
[
   {id: 0, cust: "Ben", hasSub: true,
       subCust: "Rigby", type: "s", security: '001', ticket: '99'},
   ...
   {id: 9, cust: "Uber Bank", hasSub: true,
            subCust: "Lil' Bank", type: "p", security: '456', ticket: '56'},
];
export class SubmittedComponent {
  constructor(private tradeService: TradeService) { }

  //initally show all trades
  rows = this.tradeService.getTrades();
...
以及getTrades的预期输出:

   @Injectable()
export class TradeService {
  private url = '...';  // URL to web API
  tradeArray: Trade[] = [];
  constructor(private http: Http) { }
  //-----------GETTERS---------------//
  getTradeObservable(): Observable<Trade> {
    return this.http.get(this.url)
      .map(this.extractData)
      .catch(this.handleError);
  }

  private extractData(res: Response) {
    let body = res.json();
    console.log("body:" + body);
    console.log("Entire Body.trades: " + body.trades);
    return body.trades;
  }

  getTrades(): any {
    this.getTradeObservable()
      .subscribe(
          trade => this.tradeArray.push(trade));
    return this.tradeArray;
  }
[
   {id: 0, cust: "Ben", hasSub: true,
       subCust: "Rigby", type: "s", security: '001', ticket: '99'},
   ...
   {id: 9, cust: "Uber Bank", hasSub: true,
            subCust: "Lil' Bank", type: "p", security: '456', ticket: '56'},
];
export class SubmittedComponent {
  constructor(private tradeService: TradeService) { }

  //initally show all trades
  rows = this.tradeService.getTrades();
...
服务注入和调用的一个位置:

   @Injectable()
export class TradeService {
  private url = '...';  // URL to web API
  tradeArray: Trade[] = [];
  constructor(private http: Http) { }
  //-----------GETTERS---------------//
  getTradeObservable(): Observable<Trade> {
    return this.http.get(this.url)
      .map(this.extractData)
      .catch(this.handleError);
  }

  private extractData(res: Response) {
    let body = res.json();
    console.log("body:" + body);
    console.log("Entire Body.trades: " + body.trades);
    return body.trades;
  }

  getTrades(): any {
    this.getTradeObservable()
      .subscribe(
          trade => this.tradeArray.push(trade));
    return this.tradeArray;
  }
[
   {id: 0, cust: "Ben", hasSub: true,
       subCust: "Rigby", type: "s", security: '001', ticket: '99'},
   ...
   {id: 9, cust: "Uber Bank", hasSub: true,
            subCust: "Lil' Bank", type: "p", security: '456', ticket: '56'},
];
export class SubmittedComponent {
  constructor(private tradeService: TradeService) { }

  //initally show all trades
  rows = this.tradeService.getTrades();
...
我可以在浏览器控制台中看到“整个body.trades”是我想要的数据的完整列表,但subscribe似乎没有将它们放入tradeArray中,而tradeArray最终没有定义


谢谢您的时间。

所以我想您是从一个组件调用getTrades()。如果是这样,将会发生以下情况:

  • 请求将被发送
  • 请求将在后台异步处理
  • 该方法不会等待请求被解析,并将返回tradeArray的当前值,即[]
为了避免这种情况,您可以重构组件,以便它们调用
getTradeObservable()
方法并订阅返回的
Observable

更新:另一个选择是重构您的服务以使用
Subject',并通过
Observable`将其公开给您的组件

更新:假设您对交易有以下定义

export interface Trade{
   id: number;
   cust: string;
   hasSub: boolean;
   subCust: string;
   type: string;s
   security: string;
   ticket: string;
}
您可以尝试以下方法

class TestComponent {
  data: Trade[];
  // inject service in component

  getData(){
     this.service.getTradesObservable().subscribe(data => this.data = data);
  }
}
并将getTradesObservable的定义更改为:

getTradeObservable(): Observable<Trade[]> {
    return this.http.get(this.url)
      .map(this.extractData)
      .catch(this.handleError);
  }
getTradeObservable():可观察{
返回this.http.get(this.url)
.map(此.extractData)
.接住(这个.把手错误);
}

说到这部分代码:

getTrades(): any {
    this.getTradeObservable()
      .subscribe(
          trade => this.tradeArray.push(trade));
    return this.tradeArray;
  }
由于
getTradeObservable
是异步的,因此此行:
返回this.tradeArray
将(可能)在解析可观察对象之前执行,您应该从服务中删除
getTrades
方法,而是在组件中获取由
getTradeObservable
返回的可观察对象,而不是期望整个过程返回您想要的值,您应该在订阅中按如下方式分配该值:

    @Component({
       providers:[TradeService ]
    })
    export class myComponent{
        trades:Trade[];
    constructor(tradeService:TradeService){
        tradeService.getTradeObservable().subscribe(tradeRes=>this.trades=tradeRes as Trade[]);

    }
}

你能发布你调用服务的组件吗?顺便说一句,在你的服务中订阅是一种不好的做法。你的服务应该只返回我已经更新了帖子。谢谢关于订阅者的提示,我会调查一下。@Jota.Toledo你完全可以在服务中订阅,但仍然可以公开一个可观察的,我在这里写道:是的,但在这种情况下,你使用的是一个主题,这是另一个主题。好文章,也许能帮上忙,谢谢。这很有帮助。然而,我注意到tradeArray似乎从未出现过,这可能表明存在另一个问题。我尝试给任务时间来完成:
setTimeout(function(){console.log(“Test:+this.tradeArray”);},5000)即使在5秒钟之后,数组仍然没有定义。Trade是定义为数组还是单个元素?我注意到您试图推送服务器响应的traders属性,这是一个数组,Trade是组成tradeArray的一个定义类。它与预期输出和服务器提供的json具有相同的属性——我打算将响应中的每个交易分别推送到tradeArray。谢谢你的帮助。一旦我纠正了错误的做法,我将在帖子中添加一个清理过的版本。另一个提示::http请求将始终返回POJO。只能通过调用类的构造函数方法将它们映射到类。出于这个原因,如果通过InterfaceShanks定义服务方法的返回类型更好的话,我将进行此更改,并发布一个具有正确订阅者用法的清理版本。