Reputation: 23322
I am making multiple calls to a RESTful service. Each call gets me a results. For example, it returns objects similar to the following:
{
results: {
name: "Joe",
age: 10,
}
}
I am making 5 different calls to the service with different request parameters, and I only want to return the results to my program when all 5 calls have completed and returned their object. I would like to return to the application with an array of 5 objects like the the one above.
How can this be done in Angular 2 with Observables?
This is what I have tried just earlier but I cannot figure out why it won't work:
getImage(imageUrl: string) {
console.log("Fetching from " + imageUrl);
return Observable.create((o) => {
this.httpService.get(imageUrl)
.map(res => {
return res.json();
})
.map(res => res.photos.photo[0])
.subscribe((result) => {
console.log(this.generateImageUrl(result));
o.next(this.generateImageUrl(result));
});
});
}
getImages(hashtags:string[]){
var arrayOfObservables = [];
for (var hashtag in hashtags){
var url = this.flickrAPI.fetchImagesByTag + hashtags[hashtag];
var query = this.getImage(url);
arrayOfObservables.push(query);
}
console.log(arrayOfObservables);
return Observable.forkJoin(arrayOfObservables, function(){
console.log("Fork Join Done");
return "from Fork Join with love";
});
}
And then the subscription part happens here
onSubmit() {
// First, clear FeedItems
this.feedItems = [];
var tweets$ = this.twitterService.getTweets(this.hashtagInput);
tweets$.subscribe((tweets) => {
for (var i in tweets) {
var hashtags = tweets[i].entities.hashtags;
var flicks$ = this.flickrService.getImages(hashtags);
this.subscribeToFlicks(flicks$, tweets[i]);
}
});
}
subscribeToFlicks(flicks$, tweet) {
console.log("Here");
flicks$.subscribe((results) => {
console.log("Flickr Subscription:");
console.log(results);
var twitterItem = new TwitterData(tweet.user, tweet.text);
var flickrItem = new FlickrData("null", results);
var feedItem = new FeedItem(twitterItem, flickrItem);
this.feedItems.push(feedItem);
});
}
Upvotes: 2
Views: 1894
Reputation: 202156
In fact, you need to remove the second parameter of the forkJoin
method:
getImages(hashtags:string[]){
var arrayOfObservables = [];
for (var hashtag in hashtags){
var url = this.flickrAPI.fetchImagesByTag + hashtags[hashtag];
var query = this.getImage(url);
arrayOfObservables.push(query);
}
console.log(arrayOfObservables);
return Observable.forkJoin(arrayOfObservables);
}
The second parameter corresponds to the resultSelector
. It allow you (if you want) to create the result returned by forkJoin when all events are received. If not specified, it will return the results as an array.
And subscribe on the returned observable:
getImages().subscribe(() => {
console.log("Fork Join Done");
});
Because an observable is lazy, without subscribing nothing will be executed...
Edit
You could update the étiAge method this way:
getImage(imageUrl: string) {
console.log("Fetching from " + imageUrl);
return this.httpService.get(imageUrl)
.map(res => {
return res.json();
})
.map(res => res.photos.photo[0])
.map(res => this.generateImageUrl(res));
}
Upvotes: 2