Angular Firebase - 将两个Observable合并为一个

时间:2017-10-02 16:41:05

标签: angular firebase rxjs observable

在这里挣扎太久了。我在Firebase中有两个表:

accounts
  LJHGGKJH
   prop1: 'val'
   prop2: 'val'
  IUYIUTJF
   prop1: 'val'
   prop2: 'val'

locations_per_account
  LJHGGKJH
   0: [1, 5, 6]
  IUYIUTJF
   0: [5, 2, 8]

当您看到accounts项目的locations_per_account项唯一键的唯一关键点时 - 如果它们匹配,则属于同一用户。

现在我想在我的服务中创建一个方法,它可以让我观察每个帐户及其位置,因此我可以在模板中使用async管道并提取数据。

我在这里得到所有帐户:

  getAllAccounts() {
    return this.afDb.list('accounts/', {
      query: {
        orderByChild: 'hasAccount',
        equalTo: true
      }
    })      
  }

在这里,我获得特定帐户的位置:

  getAccountLocations(optionalUid : string) {
    let uid : any;
    this.authService.authInfo$.subscribe(val => uid = val.$uid); 
    if (typeof optionalUid === 'undefined')
      return this.afDb.object('locations-per-account/' + uid);
    return this.afDb.object('locations-per-account/' + optionalUid);
  } 

所以我需要将这些流合并为一个并通过合并我应该构造返回对象的新形状。

(两个表的顺序是对称的(如果那是正确的单词),但我不确定将来它是否会保持不变,所以我想检查两个键是否匹配)。

另外要注意 - 正如您所见,我可以为每个帐户添加位置数组,但我在单独的表中执行此操作,因为我尝试使Firebase数据库尽可能保持平坦,以避免像"全表扫描&#34 ;.如果有任何想法,请提出建议 - 我在构建数据库时非常新。

2 个答案:

答案 0 :(得分:1)

使用forkJoin等待两个查询,然后将两个集合映射到id:

Rx.Observable.forkJoin([accounts$, locations$]).subscribe(results => {
  const [accounts, locations] = results
  const joined = accounts.map(account => { 
    return {
      id: account.id,
      prop1: account.prop1,
      prop2: account.prop2,
      locations: locations.filter(location => location.id === account.id)[0].loc            };
  })
  console.log(joined);
});

这假设Firebase为每个查询发出一个值,每个查询都是一个数组(我认为它来自文档)。

还假定每个id的一个帐户和位置,如果没有,那么映射将需要变得更复杂。

这是一个模拟场景的CodePen。 CodePen

答案 1 :(得分:0)

所以在你的情况下,伪代码看起来像这样:

Observable.forkJoin([this.getAllAccounts(), this.getAccountLocations()])
   .subscribe(results => {
       console.log(results)
   }
);

关于管理可观察对象的几篇文章:Cory RylanTor