2016-11-14 2 views
2

У меня вопрос о работе с отношениями «многие-ко-многим» в Firebase. В принципе, я пытаюсь создать объект профиля пользователя из нескольких путей внутри своих данных Firebase. Я попытался создать функцию, которая возвращает наблюдаемый, а затем обновляет данные в наблюдаемом виде в виде вложенных наблюдаемых данных захвата из Firebase.AngularFire2 - вложенный FirebaseObjectObservable не будет запускать вложенный вызов Firebase

Проблема в том, что вложенные наблюдаемые никогда не вызываются из того, что я могу сказать. Я бил головой об этом часами без каких-либо реальных успехов. Может ли кто-нибудь сказать, что я делаю неправильно? Я чувствую, что это довольно распространенная проблема, которая решается.

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; 
    }); 
} 

ответ

5

Вложенные наблюдаемые никогда не называются, потому что они никогда не подписываются - наблюдаемые ленивы.

Вы могли бы сделать что-то вроде этого, вместо:

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; 
     } 
    ); 
    }); 
} 
+0

cartant, вы самое лучшее. Я понял, что это один из тех случаев, когда я буду многократно использовать такую ​​функциональность для множества разных «совместных событий», которые я буду делать. Это прекрасно работает и на самом деле демонстрирует краткий способ сделать это :) Cheers! –

+0

На самом деле мне было интересно: если бы я хотел, чтобы мой пользовательский интерфейс автоматически обновлял данные о видео, если они меняются в другом месте, мне нужно будет переработать это, чтобы использовать подписчиков каждого отдельного видео из базы данных Firebase? В текущей версии видеоданные загружаются только один раз, но не обновляются, если они обновляются в базе данных. Я думаю, что я хотел бы использовать эту же функциональность для агрегирования сообщений между пользователями или фида разных сообщений. –

+0

Да, вам нужно будет изменить его. Код в ответе будет только переизлучаться, если пользователь изменится. Если вы хотите переизлучить, когда что-либо изменится, вы можете использовать 'combLatest' вместо' forkJoin'. И удалите оператор 'first'. – cartant