Reputation: 1502
This is pretty straight forward, so I'm not sure why it's not working.
I have a service giving me an observable. I have a couple of rxjs streams which contribute to it like so:
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)
);
}
Long story short, after a request the albumSearchStream gets an array of type EnvAlbum.
This is all happening within a service on Search.
This service is being injected into my Page controller, and in the constructor I am doing
this.albumResults = this.spotifyService.albumSearchStream;
where albumResults is going to be Observable of type EnvAlbum[].
Then in the template I am using a basic ngFor on this observable like so:
<ion-card *ngFor="let result of albumResults | async" >
<ion-card-header>
{{ result }}
</ion-card-header>
</ion-card>
However, then I get the following error:
I am beyond stumped as to why this error is occurring.
NB: On subscribe, it is correctly outputting an array of objects
Upvotes: 3
Views: 1916
Reputation: 202316
I think the problem that albumResults
isn't a property of your component (it will be undefined) at the beginning so the async
pipe can't subscribe on it. It seems to be set when you click to trigger the search
method...
You could try to wrap the ngFor
within an ngIf
with the desugared expression
<template [ngIf]="albumResults"> <------
<ion-card *ngFor="let result of albumResults | async" >
<ion-card-header>
{{ result }}
</ion-card-header>
</ion-card>
</template>
or initialize the albumResults with a fake observable.
Edit
I would refactor your service code this way:
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);
}
);
}
and set the albumResults
property in your component this way:
constructor(private spotifyService:SpotifyService) {
this.albumResults = this.spotifyService.albumResults;
}
See this plunkr: https://plnkr.co/edit/IrsZ9P3wff2YXyjRRGTw?p=preview.
Upvotes: 2