0

I'm new to angular 2 and would like to make nested http calls where one call is dependent on the next call. My code is as follows in service:

getUserPosts(): Observable<any[]>{
    return this.http.get(this.apiUserURL + this.userId + '/')
        .map((response: Response)  => response.json())  
        .flatMap((users) => {
            return Observable.forkJoin(
                users.map(user=>
                    this.http.get(this.apiUserPostURL + user.id)
                    .flatMap(response => response.json())   
                )   
            )
        })
}

in Components I have:

ngOnInit() {
this.results = this.postsService.getUserPosts()
  .subscribe(posts => {  this.posts = posts
    console.log(posts);
  })   
}

when I do that I get the last post of every user but not all posts. (I have 3 posts for every user, and I have two users in my database, but below I get only one post of every user:

(2) [Object, Object]
0:Object
1:Object

solution expected: get all posts from all users like this:

(6) [Object, Object, Object, Object, Object, Object]

when I change the last part of my service to the following:

users.map(user=>
    this.http.get(this.apiUserPostURL + user.id)
    .map(response => response.json())   
)   

I get two arrays of 3 posts each and I don't know how to access those posts with *ngFor:

(2) [Array(3), Array(3)]
0:Array(3)
  0:Object
  1:Object
  2:Object
1:Array(3)
  0:Object
  1:Object
  2:Object

Solution expected: reach out directly to the arrays without having one array of objects for every user but instead one array containing all objects:

(6) [Object, Object, Object, Object, Object, Object]

I even tried to do something else which I thought will help by adding .flatMap to my component as follows:

ngOnInit() {
this.results = this.postsService.getUserPosts()
 .flatMap(posts => this.posts = posts)
  .subscribe(posts => {  this.posts = posts
    console.log(posts);
  })    
}

but I got two separate arrays, each array is related to each user with all his posts, *ngFor only picks the latest user and ignore the other posts from the other user:

(3) [Object, Object, Object]
   0: Object
   1: Object
   2: Object
(3) [Object, Object, Object]
   0: Object
   1: Object
   2: Object

Solution expected: merge both arrays into one array as:

(6) [Object, Object, Object, Object, Object, Object]

Can anyone please help in figuring out how to solve this problem? Thanks a lot!

4
  • try to use map instead of flatMap here: this.http.get(this.apiUserPostURL + user.id) .map(response => response.json()) Commented May 25, 2017 at 23:59
  • @Julia Passynkova i did that on my second part of my post above and i don't get the desired solution. Any other suggestion? Commented May 26, 2017 at 17:52
  • use .flatMap((users) => {...]).map(x=> [].concat.apply([],x)) Commented May 26, 2017 at 19:20
  • @Julia Passynkova You are genius. It worked like a charm. Commented May 26, 2017 at 21:07

1 Answer 1

0

Thank you to Julia Passynkova for her answer to allow to solve my problem. this the final solution by adding the last line of concat.apply() to my service:

getUserPosts(): Observable<any[]>{
return this.http.get(this.apiUserURL + this.userId + '/')
    .map((response: Response)  => response.json())  
    .flatMap((users) => {
        return Observable.forkJoin(
            users.map(user=>
                this.http.get(this.apiUserPostURL + user.id)
                .flatMap(response => response.json())   
            )   
        )
    }).map(x=> [].concat.apply([],x))

}

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.