Reputation: 7328
I have angular2 project and in it I have this class:
class Application {
id: number;
last_android_releasse_url: string;
last_android_releasse: Release;
last_ios_releasse_url: string;
last_ios_releasse: Release;
}
I fetch all applications and load them with the | async pipe this way:
this.asyncApps = this.appService.getAll(this.params)
.do((data: any) => {
this.count = data.count;
}).map(data => {
return data.apps;
});
What I need is to load every release object for every app inside the data.apps and to return observable for the asyncApps to work with the async pipe. I wasn't sure how to ask my question so I accept proposals for title change. So the final code should do something like this:
this.asyncApps = this.appService.getAll(this.params)
.do((data: any) => {
this.count = data.count;
}).map(data => {
for (let app of data.apps) {
this.http.get(app.last_android_releasse_url).subscribe(
release_data => {
app.last_android_releasse = release_data.json().last_android_releasse;
},
error => this.alertService.showError(error.etext)
);
this.http.get(app.last_ios_releasse_url).subscribe(
release_data => {
app.last_ios_releasse = release_data.json().last_ios_releasse;
},
error => this.alertService.showError(error.etext)
);
}
return data.apps;
});
And this one works, but I was thinking about something with flatMap or forkJoin. Just doesn't seem like the right solution to me. Could you help me clear that please.
Upvotes: 0
Views: 258
Reputation: 9341
You are right, you can use flatMap . Thanks for asking , here is what I attempted.
this.asyncApps = this.appService.getAll(this.params)
.do((data: any) => {
this.count = data.count;
})
.flatMap(data => Observable.from(data.apps))
.flatMap(app => Observable.forkJoin(
this.http.get(app.last_android_releasse_url).map(d => d.json().last_android_releasse),
this.http.get(app.last_ios_releasse_url).map(d=>d.json().last_ios_releasse))
.first()
.map(res => Object.assign(app, {
last_android_releasse : res[0],
last_ios_releasse : res[1]})
)
);
Let me know if its working.
Here is what I did
this.asyncApps = this.appService.getAll(this.params)
Perform network call
.do((data: any) => {
this.count = data.count;
})
Update count to number of result
.flatMap(data => Observable.from(data.apps))
Convert stream of list to stream of individual items
.flatMap(app => Observable.forkJoin(
For each app , am converting app without response to app with response data. As its asynchronous and needs Observable, used flatMap.
this.http.get(app.last_android_releasse_url).map(d => d.json().last_android_releasse),
this.http.get(app.last_ios_releasse_url).map(d=>d.json().last_ios_releasse))
Do separate calls in parallel and combine the result in stream of array
.first()
Get the first result
.map(res => Object.assign(app, {
last_android_releasse : res[0],
last_ios_releasse : res[1]})
)
convert the result to app with result
);
Finally we should have a stream of apps with response in each of them.
Upvotes: 1