AngularFire2 - nested FirebaseObjectObservable won

2019-07-10 07:37发布

问题:

I've got a question about dealing with working with many-to-many relationships in Firebase. Basically, I'm trying to build a user profile object from multiple paths inside of my Firebase data. I've tried building a function that returns an observable and then updates the data in that observable as a nested observable grabs data from Firebase.

The problem is that the nested observable doesn't ever get called, from what I can tell. I've been beating my head against this for hours without any real success. Can anyone tell what I'm doing wrong? I feel this is a pretty common problem that gets solved.

public getUserProfile(data) {

    return this._af.database.object(`/social/users/${data.id}`).map((user) => {
        for ( let vidKey in user.videos) {

            // Once the code hits this line, it never fires at all :(
            this._af.database.object(`/social/videos/${vidKey}`).map((video) => {
                user.videos[vidKey] = video;
            });
        }
        return user;
    });
}

回答1:

The nested observable is never called because it's never subscribed to - observables are lazy.

You could do something like this, instead:

public getUserProfile(data) {

  return this._af.database
    .object(`/social/users/${data.id}`)

    // Switch to the joined observable

    .switchMap((user) => {

      let vidKeys = Object.keys(user.videos);

      // Use forkJoin to join the video observables. The observables will
      // need to complete, so first is used. And use forkJoin's selector to
      // map the videos to the user and then return the user.

      return Observable.forkJoin(
        vidKeys.map((vidKey) => this._af.database
          .object(`/social/videos/${vidKey}`)
          .first()
        ),
        (...videos) => {
          vidKeys.forEach((vidKey, index) => { user.videos[vidKey] = videos[index] });
          return user;
        }
      );
    });
}