RXJ组成一个可观察的列表,然后合并(Firebase)

RXJ组成一个可观察的列表,然后合并(Firebase),firebase,firebase-realtime-database,rxjs,Firebase,Firebase Realtime Database,Rxjs,我正在尝试合并一个可观察的列表,但没有运气使用zip或其他地图 我想做的是获取给定艺术家Id的流派列表。我使用的是firebase,所以它是一个nosql数据库。我有一个“genresPerArtist”列表,它是一个艺术家键列表,每个艺术家键都有一个流派键列表。 结构: { genresPerArtist: { artist1: { genre1: true, genre2

我正在尝试合并一个可观察的列表,但没有运气使用zip或其他地图

我想做的是获取给定艺术家Id的流派列表。我使用的是firebase,所以它是一个nosql数据库。我有一个“genresPerArtist”列表,它是一个艺术家键列表,每个艺术家键都有一个流派键列表。 结构:

    { 
         genresPerArtist: {
             artist1: {
                 genre1: true,
                 genre2: true,
                 genre3: true
            }
        },
         genres: {
             genre1: {
                name: 'Alternative'
             },
             genre2: {
                name: 'Jazz'
             } 
        }
    }
以下是我拥有的函数的开始:

getGenresByArtistId(artistId: string): Observable<any> {
     return this.db.list(`/genresPerArtist/${artistId}`)
         .flatMap((genres: IDictionary[]) => {
             return genres.map(genre => this.db.list(`/genres/${genre.$key}`));
             // return Observable.zip(obvs);
         });
getGenresByArtistId(artistId:string):可观察{
返回此.db.list(`/genresPerArtist/${artistId}`)
.flatMap((类型:IDictionary[])=>{
返回genres.map(genre=>this.db.list(`/genres/${genre.key}`));
//返回可观测.zip(obvs);
});

我真的不确定如何处理从genresPerArtist那里得到的列表。我想做的是获取每个genre.key(genre1、genre2、genre3),并使用每一个从“流派”中获取值。我想我可以返回一个.zip,然后映射到该值,但我没有从zip中得到响应。

您可以尝试以下操作,即返回
genresPerArtist
返回一个
map

从'rxjs/Observable'导入{Observable};
导入'rxjs/add/operator/mergeMap';
从'rxjs/observeable/zip'导入{zip};
getGenresByArtistId(artistId:string):可观察{
返回此.db.list(`/genresPerArtist/${artistId}`)
.mergeMap((类型:Map)=>
zip(Array.from(genres.keys()).map(genre=>this.db.list(`/genres/${genre}`)))
}
编辑:另一个选项是

import 'rxjs/add/operator/mergeMap';
import 'rxjs/add/operator/toArray';

getGenresByArtistId(artistId: string): Observable<Genre[]>{
       return this.db.list(`/genresPerArtist/${artistId}`)
       .mergeMap((genres: Map<string, boolean>) => Array.from(genres.keys())
       .mergeMap(genres=> genres)
       .mergeMap(genre => this.db.list(`/genres/${genre}`))
       .toArray();
    }
导入'rxjs/add/operator/mergeMap';
导入'rxjs/add/operator/toArray';
getGenresByArtistId(artistId:string):可观察{
返回此.db.list(`/genresPerArtist/${artistId}`)
.mergeMap((genres:Map)=>Array.from(genres.keys())
.mergeMap(类型=>genres)
.mergeMap(genre=>this.db.list(`/genres/${genre}`)
.toArray();
}

基本上,我是手动将结果展平到一个数组中的。我花了很长的时间来让它更容易跟随卡坦特,谢谢,这包括了我所需要的


值为“流派”时,您是指与流派键关联的整个对象吗?请指定该方法的返回类型好吗?(可观察列表)是的,我想我会得到与类型键关联的整个对象。我最终会从中得到“name”属性。很少元素应该是数组,您将所有元素都显示为objects。请看一看。@cartant,谢谢,forkJoin是我需要的,请参阅我发布的答案。如果您想发布答案,您可以,我将标记为正确。看起来mergeMap和flatMap是一样的。这里的问题是,如果我订阅从getGenresByArtistId发出的observable,它将永远无法解析。(它被调用,但从未返回任何项)是的,flatMap是mergeMap的别名。您是否收到任何错误?是第一个请求(genresPerArtis)被发送?没有错误。是的,/genresPerArtist被发送并解析,它们也为每种类型构建了一个可观察的数组。但是当我订阅最终结果时,没有任何解析。很高兴知道,让我们尝试另一个variant@mrshickadance运气好吗?
import 'rxjs/add/operator/mergeMap';
import 'rxjs/add/operator/toArray';

getGenresByArtistId(artistId: string): Observable<Genre[]>{
       return this.db.list(`/genresPerArtist/${artistId}`)
       .mergeMap((genres: Map<string, boolean>) => Array.from(genres.keys())
       .mergeMap(genres=> genres)
       .mergeMap(genre => this.db.list(`/genres/${genre}`))
       .toArray();
    }
// Compose an observable based on the genresPerArtist:
        return this.db.list(`/genresPerArtist/${artistId}`)
        // Each time the genresPerArtist emits, switch to unsubscribe/ignore any pending user queries:
        .switchMap(genres => {
            // Map the genres to the array of observables that are to be joined.
            let genreObservables = genres.map(genre => this.db.object(`/genres/${genre.$key}`).first());
            return Observable.forkJoin(...genreObservables);
        });