2017-10-02 6 views
1

Luttant un peu trop longtemps ici. J'ai deux tables à Firebase:Angulaire Firebase - fusionner deux Observables en un

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

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

Comme vous le voyez accounts points clés de point unique à clé unique de locations_per_account article - si elles correspondent ils appartiennent au même utilisateur.

Maintenant, je veux faire une méthode dans mon service qui me fournirait observable de chaque compte et de ses emplacements, de sorte que je pourrais utiliser async pipe dans mon modèle et extraire les données.

Ici, je reçois tous les comptes:

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

Ici je reçois des emplacements de compte en particulier:

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

donc j'ai besoin de fusionner ces flux en un seul et en fusionnant je construire la nouvelle forme de retour d'objet. (L'ordre des deux tables est symétrique (si c'est le bon mot), mais je ne suis pas sûr qu'il restera le même dans le futur, donc je voudrais vérifier si les deux clés correspondent). Aussi à noter - comme vous pouvez le voir, je pourrais ajouter des emplacements array à chaque compte, mais je le fais dans une table séparée parce que j'essaie de rendre ma base de données Firebase aussi plate que possible, pour éviter des choses comme "Full table scan" . S'il vous plaît avis si des pensées - je suis assez nouveau dans la construction de bases de données.

+0

regardez 'obsevables.forkjoin' –

+0

... Je pensais pourquoi je n'ai jamais vu' forkjoin' dans http://reactivex.io/documentation/operators.html alors je 'ctrl + F' et j'ai trouvé" An Alphabetical Liste des opérateurs observables "... Eh bien c'est amusant de lire ... Merci @Rahul Singh –

+1

pas de problème. Plus d'infos cam peut être trouvé ici aussi [rxjs] (https://rahulrsingh09.github.io/AngularConcepts/ngrx/rxjs) –

Répondre

1

Utilisez forkJoin d'attendre pour les deux requêtes, la carte puis les deux définit ensemble sur 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); 
}); 

Cela suppose que Firebase émet une valeur unique pour chaque demande de recherche, chacun d'eux est un a rray (ce que je pense qu'il fait, à partir des docs).

Présuppose également un compte et un emplacement par ID, sinon le mappage devrait être plus compliqué.

Voici un CodePen qui simule le scénario. CodePen

0

donc dans votre cas, le code de pseudo pourrait ressembler à ceci:

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

quelques articles sur la gestion des observables: Cory Rylan, Tor

+0

Pourriez-vous montrer comment forkJoin dans mon cas? :) Maintenant, je sais avec certitude que 'accounts' et' locations_per_account' ne sont pas symétriques, donc je ne dois forkjoin que si leurs propriétés '$ key' correspondent. Et perdre des données n'est également pas une option :) Vous avez le temps jusqu'à demain :)) J'espère que je vais le résoudre puis –

+0

@incognito J'ai mis à jour la réponse, laissez-moi savoir comment ça se passe – FussinHussin

+0

Cela ne fonctionnera pas. Il retournera une erreur Si je ne passe pas 'optionUid' à' getAccountLocations() '.J'utilise cette méthode comme méthode universelle pour les deux - actuellement loggden dans l'utilisateur et tout autre utilisateur si je passe 'optionUid' à cette méthode –