Angular Firebase - merge two Observables into one

时间秒杀一切 提交于 2021-02-07 10:44:11

问题


Struggling a bit too long here. I have two tables in 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]

As you see accounts item's unique key points to locations_per_account item's unique key - if they match they belongs to the same user.

Now I want to make one method in my service which would provide me observable of every account and its locations, so I could use async pipe in my template and extract the data.

Here I get all accounts:

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

Here I get locations of particular account:

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

So I need to merge these streams into one and by merging I should construct the new shape of returning object.

(the order of both tables is symmetric (if thats the right word), but I am not sure if it will stay the same in the future, so i would like to check if both keys match).

Also to note - as you see, I could add locations array to every account, but I do it in separate table because I try to make my Firebase database as flat as possible, to avoid things like "Full table scan". Please advice if any thoughts - I am pretty new in building databases.


回答1:


Use forkJoin to wait for both queries, then map the two sets together on 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);
});

This presumes that Firebase is emitting a single value for each query, each of which is an array (which I think it does, from the docs).

Also presumes one account and location per id, if not then the mapping would need to get more complicated.

Here's a CodePen which simulates the scenario. CodePen




回答2:


so in your case, the pseudo code could look like this:

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

a couple articles on managing observables: Cory Rylan, Tor



来源:https://stackoverflow.com/questions/46529904/angular-firebase-merge-two-observables-into-one

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!