2017-06-18 59 views
0

我試圖將可觀察列表組合起來,但沒有使用zip或其他地圖的運氣。RxJs創建一個Observable列表,然後合併(Firebase)

我想要做的是獲得給定藝術家ID的流派列表。我使用的是firebase,所以它是一個nosql數據庫。我有一個'genresPerArtist'列表,它是一個Artist鍵列表,每個Artist鍵都有一個Genre鍵列表。 結構:

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

我真的不知道什麼做的,我得到genresPerArtist回來就行。我想要做的是採取每個genre.key(genre1,genre2,genre3),並使用每個從'流派'中獲取值。我想我可以返回一個.zip,然後映射,但我沒有得到zip的迴應。

+0

「genre」的值是否意味着與流派密鑰關聯的整個對象?你能指定方法的返回類型嗎? (Observable ist helpful) –

+0

是的,我想我會得到與流派關鍵相關的整個對象。我最終會從那裏獲得'name'屬性。 – mrshickadance

+0

幾個元素應該是數組,你將它們全部顯示爲對象 – Skeptor

回答

0

@cartant,謝謝,包括我需要的,forkJoin

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

你可以嘗試用以下asumming是的genresPerArtist返回返回Map<string, boolean>

import { Observable } from 'rxjs/Observable'; 
import 'rxjs/add/operator/mergeMap'; 
import { zip } from 'rxjs/observable/zip'; 

getGenresByArtistId(artistId: string): Observable<Genre[]>{ 
    return this.db.list(`/genresPerArtist/${artistId}`) 
    .mergeMap((genres: Map<string, boolean>) => 
    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(); 
    } 

基本上林扁平化的結果合併到一個數組手動。我花了很長的路要讓它更容易遵循

+0

它看起來像mergeMap和flatMap是一樣的。這裏的問題是,如果我訂閱從getGenresByArtistId發出的observable,它永遠不會解決。 (它被調用,但從不返回任何項目) – mrshickadance

+0

是的,flatMap是mergeMap的別名。你是否有任何錯誤?第一個請求(genresPerArtis)是否被髮送? –

+0

沒有錯誤。是的,/ genresPerArtist被髮送並解決,他們的每個類型的Observables數組也被構建。但是當我贊同最終結果時,沒有任何結果。 – mrshickadance

相關問題