Flatten/Chain multiple nested firebase Observables -
i'm trying use angularfire2. querying , works fine below.
i want combine all/most of observables one:
gettournamentwithrounds(key):observable<tournament> { return this.af.database .object(`/tournaments/${key}`) .map(tourney => { let t = tournament.fromjson(tourney); this.af.database.list('players', { query: { orderbychild: 'tournament_key', equalto: key } }) .map(player.fromjsonlist) .subscribe(ps => { t.players = ps; }); this.af.database.list('rounds', { query: { orderbychild: 'tournament_key', equalto: key } }) .map(round.fromjsonlist) .subscribe(rs => { t.rounds= rs; }) return t; }) } i wondering if join observables , output single subscribe function.
i know when initial data has been loaded , perform additional computation in controller before outputting view.
also, how extended include matches each round?
my extension above code be:
... this.af.database.list('rounds', { query: { orderbychild: 'tournament_key', equalto: key } }) .map(rounds => { return rounds.map((round) => { let r = round.fromjson(round); this.af.database.list('matches', { query: { orderbychild: 'round_key', equalto: round.$key } }) .map(match.fromjsonlist) .subscribe(matches => { r.matches = matches; }) return r; }) }) .subscribe(rs => { t.rounds= rs; }) ...
you use combinelatest operator combine players , rounds tournament:
gettournamentwithrounds(key): observable<tournament> { return this.af.database .object(`/tournaments/${key}`) .combinelatest( this.af.database.list('players', { query: { orderbychild:'tournament_key', equalto: key } }), this.af.database.list('rounds', { query: { orderbychild:'tournament_key', equalto: key } }) ) .map(([tourney, players, rounds]) => { let t = tournament.fromjson(tourney); t.players = player.fromjsonlist(players); t.rounds = round.fromjsonlist(rounds); return t; }); } whenever of observables emits, latest values re-combined , new tournament emitted.
extending include each round's matches little more complicated, each round's key needed matches query.
the emitted rounds can mapped array of list observables matches , forkjoin can used join observables, forkjoin selector function being used combine matches rounds. switchmap used emit rounds.
gettournamentwithrounds(key): observable<tournament> { return this.af.database .object(`/tournaments/${key}`) .combinelatest( this.af.database.list('players', { query: { orderbychild:'tournament_key', equalto: key } }), this.af.database.list('rounds', { query: { orderbychild:'tournament_key', equalto: key } }) .switchmap(rounds => { observable.forkjoin( rounds.map(round => this.af.database.list('matches', { query: { orderbychild: 'round_key', equalto: round.$key } }).first()), (...lists) => rounds.map((round, index) => { let r = round.fromjson(round); r.matches = match.fromjsonlist(lists[index]); return r; }) ) }) ) .map(([tourney, players, rounds]) => { let t = tournament.fromjson(tourney); t.players = player.fromjsonlist(players); t.rounds = rounds; return t; }); }
Comments
Post a Comment