3

I'm unable to find a clean way of fetching nested data the rxjs way.

There's an observable returning all users and an observable returning all posts given a user id.

getUsers(): Observable<User[]>

and

getPosts(id: string): Observable<[]>

How would I return a list of users including their posts?

At the moment I prepare the data using 2 nested subscriptions.

nestedFetch() {
  this.service.getUsers()
  .subscribe(
    res => {
      res.forEach((user) => {
        this.service.getPosts(user.Id).subscribe(
          posts => {
            user.posts = posts;
            this.users.push(user);
          },
          err => console.log('something went wrong: ' + err)
        )
      })
    },
    err => console.log('something went wrong: ' + err)
  );
}

I would rather use operators something like this. But how can i return users including their posts?

nestedFetch() {
  this.service.getUsers().pipe(
    map(users => users.map(u => this.membership.getPosts(u.id))),
    mergeMap(posts => forkJoin(posts))
  ).subscribe(
    res => this.posts = posts, //returns only posts but not users
    err => console.log('something went wrong: ' + err)
  )
}
1

1 Answer 1

2

An inner pipe helps to extend the user by his posts.

this.service.getUsers().pipe(
  switchMap(users => {
    const postsRequests$ = this.users.map(user => this.service.getPosts(user.id).pipe(
      // example for a error catch which would lead to an empty array not breaking the forkJoin
      // catchError(err => of([])),
      map(posts => ({ ...user, posts })),
    ));

    return forkJoin(postsRequests$);
  }),
).subscribe(/* ... */);
Sign up to request clarification or add additional context in comments.

3 Comments

Would the subscribe catch errors thrown by the inner pipe?
@F.H. Pipe is just linking together (free-point-style) one or more curried functions. So what you need to know is if forkJoin() errors when it's inner observables error. The answer is yes it does. If any of the inner observables error, you never get a result from forkJoin, just the error.
You can additionally handle errors with the rxjs catchError operator, I extended my answer

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.