* ngFor无法阅读财产'订阅'给定类型数组

时间:2016-06-01 10:12:00

标签: javascript typescript angular reactive-programming rxjs

这很简单,所以我不确定它为什么不起作用。

我有一项服务给我一个可观察的。 我有几个rxjs流,它们就像这样:

search(searchTerm: string {

  this.searchStream = this.http.get("${this.baseUrl}searchq=${searchTerm}");

  this.resultStream = this.searchStream.map(
    data => {
      let obj = data.json();
      return {
        artists: obj.artists.items,
        albums: obj.albums.items,
        tracks: obj.tracks.items
      };
    },
    err => console.error(err),
    () => console.log('getRepos completed')
  );

  this.albumSearchStream = this.resultStream.map(
    searchResults => {
      console.log("mapping albums");
      return searchResults.albums
    },
    err => console.log("unable to get albums")
  );
  this.albumSearchStream.subscribe(
    albums => console.log(albums)
  );
}

长话短说,请求 albumSearchStream 获取 EnvAlbum 类型的数组。

这一切都发生在搜索服务中。

此服务正在注入我的Page控制器,并在我正在构建的构造函数中

this.albumResults = this.spotifyService.albumSearchStream;

其中 albumResults 将是可观察类型为EnvAlbum []

然后在模板中,我在这个可观察对象上使用基本的ngFor:

<ion-card *ngFor="let result of albumResults | async" >
        <ion-card-header>
            {{ result }}
        </ion-card-header>
    </ion-card>

然而,我收到以下错误: enter image description here

我无法理解为什么会发生这种错误。

注意:在订阅时,它正在输出一个对象数组

1 个答案:

答案 0 :(得分:1)

我认为albumResults在开始时不是您的组件的属性(它将是未定义的)的问题,因此async管道无法订阅它。当您单击以触发search方法...

时,似乎已设置

您可以尝试将ngFor包含在ngIf中,并使用desugared表达式

<template [ngIf]="albumResults"> <------
  <ion-card *ngFor="let result of albumResults | async" >
    <ion-card-header>
      {{ result }}
    </ion-card-header>
  </ion-card>
</template>

或使用虚假的可观察对象初始化albumResults。

修改

我会以这种方式重构您的服务代码:

albumResults = new Subject();

search(searchTerm: string) {
  this.searchStream = this.http.get(...);

  this.resultStream = this.searchStream.map(
    data => {
      let obj = data/*.json()*/;
      return {
        artists: obj.artists.items,
        albums: obj.albums.items,
        tracks: obj.tracks.items
      };
    }
  );

  this.albumSearchStream = this.resultStream.map(
    searchResults => {
      return searchResults.albums
    }
  );
  this.albumSearchStream.subscribe(
    albums => {
      this.albumResults.next(albums);
    }
  );
}

并以这种方式在组件中设置albumResults属性:

constructor(private spotifyService:SpotifyService) {
  this.albumResults = this.spotifyService.albumResults;
}

请参阅此plunkr:https://plnkr.co/edit/IrsZ9P3wff2YXyjRRGTw?p=preview