3

I need to make nested http calls in my angular app. First call returns the list of venues, then using each venue id i have to make multiple api calls to get details of each venue. Here is my code,

service.ts

GetResponse(){
     return this.http.get('someurl')//Returns list of venues
     .map(res => res.json())
     .flatMap(
     (result) =>{
       return 
         Observable.forkJoin(result.response.groups[0].items.map
                          ((data) => this.getDetailss(data))
     )});
}


getDetailss(venues) {
  return this.http.get('some url'/venues.id)// returns details of single venue
}

component.ts ,

this.service.GetResponse().subscribe(
(response)=> console.log(response),//Prints array of observables
(error)=>console.log(error)
);

I am receiving an array of observables in my component.How can i retrieve data from it in json form?

2 Answers2

0

Since getDetailss(venues) returns the this.http.get() return value (which is an observable), in this statement ((data) => this.getDetailss(data)) you should put the map() method after the call..

It should be:

Observable.forkJoin(
    result.response.groups[0].items.map(
        (data) => {
            return this.getDetailss(data).map(response => response.json());
        })

Though in my opinion, consider using async and await to get rid of the ugly nesting (async and await are available for typescript 2.1.x and above)..

samAlvin
  • 1,648
  • 1
  • 11
  • 35
  • `async` and `await` are es6 and because this is an angular question, it's typescript code so they are not available. – Supamiu Aug 02 '17 at 07:36
  • @Supamiu using typescript 2.1 or above, downleveling `async` and `await` to ES3/ES5 is possible for the compiler though.. here's the reference: https://blog.mariusschulz.com/2016/12/09/typescript-2-1-async-await-for-es3-es5#downleveling-async-await-to-es3-es5.. ah, then let me updated my answer – samAlvin Aug 02 '17 at 07:42
0

If you want an array of all venue details you can use combineLatest operator:

this.http.get('someurl')
    .map(res => res.json())
    .flatMap(result => {
        const venueRequests = [];
        for (const venue of result.someproperty) {
            venueRequests.push(this.http.get('someurl' + venue.id))
        }
        //This will change an Observable<Response>[] into an Observable<Response[]>
        return Observable.combineLatest(venueRequests);
    });

Then you can simply subscribe to that and add .map (res => res.json()) and you'll get an array of venue details.

Supamiu
  • 8,501
  • 7
  • 42
  • 76