2017-08-14 13 views
2

RxJが比較的新しく、switchMap演算子を使用して複数の項目を処理した後に1つの操作を連鎖させることができません。複数の項目が処理された後にRxJSで単一の操作が実行される

シナリオ:バックエンドデータを使用してドロップダウンリストのオブジェクト配列を生成し、ドロップダウンの選択された値を設定するための1つの操作をチェーンします。

問題の説明に役立つ非正常なコードは次のとおりです。

this.sub = this.dataService.getUserData() 
    .switchMap((data) => Observable.from(data)) // create new data stream from inner data set 
    .map((data: any) => { 
     return { value: data._id, viewValue: data.firstName + ' ' + data.lastName }; 
    }) // create data structure for drop down 
    .subscribe((data) => { 
     this.userDropDown.push(data); // this operation needs to run once per item emitted, and is working 
     this.patchFormData(); // <-- However, this only needs to run once 
    }, 
    (error) => console.log("error", error) 
    ); 

私は問題をモーフィングが、新しいオブジェクト配列は、ソースデータをオフに基づいて取得問題、すなわちA)の全体を解決することができませんし、b)の完了後に、単一の操作を実行し、さまざまな演算子を試してみました。

大変助かりました。

  • S.アローラ

、ありがとう - UPDATE:作業の最終バージョンは、ここでマイナーな構文の修正と以下の回答に基づいています。

this.sub = this.dataService.getUserData() 
    .map((data: any[]) => { 
     return data.map((x: any) => { 
      return { value: x._id, viewValue: x.firstName + ' ' + x.lastName }; 
     }); 
    }) 
    .subscribe((data: any) => { 
     this.userDropDown = data; 
     this.patchFormData(); 
    }, 
    (error) => console.log("error", error) 
    ); 
+0

は 'this.dataService.getUserData()'は配列を返しますか? – CozyAzure

答えて

1

実は、あなたは.switchMap()はまったく必要ありません。 Observable.from()を使用して複数の排出量を作成しているだけで、ドロップダウン値を1つずつ更新しない限り、完全に不要です。

あなたができることは、配列を返すだけです。.map()を使用して配列を変換し、それをドロップダウンリストに割り当てます。

this.sub = this.dataService.getUserData() 
//this map is a function of Observable 
    .map((data: any[]) => { 
     //this map is a function of array, not observable. 
     //use this to transform the data 
     return data.map(x => ({value: x._id, viewValue: x.firstName + ' ' + x.lastName})) 
    }) 
    .subscribe((data) => { 
      //assign your values to your dropdown list, and not pushing it one by one. 
      this.userDropDown = data; 
      this.patchFormData(); 
     }, 
     (error) => console.log("error", error) 
    ); 

さて、あなただけ(API呼び出しである)あなたの観察可能な1個の発光を有する、そして、あなたの.subscribe()機能で、あなたのthis.userDropDownthis.patchFormData()は両方一度だけ実行されます。

+0

残念なことに.switchmapはneed.the getUserDataの呼び出しに必要なサービスを提供しています。私はgraphqlを使用しています。 switchMapはその単一のコレクションを別々に発行されるアイテム(ユーザーごとに1つずつ)に変換し、マップを使用してそれを1つずつ変換することができます。私はlodashを使ってコレクション全体を扱うことを考えましたが、可能であればRxJのアプローチに固執しようとしています。 – sarora

+0

@saroraこれは、私の答えのちょうどポイントです。あなたは観察可能なものを介してそれらを1つずつ変換する必要はありません。 arrayの['.map'](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map)を使ってそれらを変形することができます。 – CozyAzure

+0

感謝します!私はRxJsパイプライン内で通常の.map演算子*を使ってコレクションを操作するとは思わなかった。とても気の利いた!私が.switchmapのアプローチに入った後は、単一の操作を連鎖させることが不必要に難しくなりました。 – sarora

関連する問題