NEM-libraryを触りながらRxJSを学ぶ

正直言うと今までObservable良く分かんねぇなぁと思いながら使ってました。良く分からないけど、なんかこれオシャレじゃない?的な。

日本語の記事も少ないですし、抽象的な記事が多いのでいまいち理解が進まない。

以下の記事を書く際に参考にしたnem-library-examplesが結構良いサンプルだったので、少し理解が進んだような気がしていましたが、まだ9割ぐらいは雰囲気スクリプターからは抜け出せていませんでした。 tadajam.hateblo.jp

その時参考にしたページ github.com

この辺り詳しい人が誰か教えてくれないかなぁなどと思っていたところ、神が現れました。

NEMの守護神みなりんさん経由で、以下記事を読んでくれたNEM-Libraryの中の人ことAleixさんから連絡があり、もっとイケている書き方を教えてもらいました。 tadajam.hateblo.jp

神々への感謝の気持ちを忘れないために、そしてどこかの誰かの参考になればと記事を残しておきます。

修正前

記事にもともと載せていたソースが以下です。

一つ目のAPIの結果を受けて二つ目のAPIをコールする流れですが、せっかくのRxJSの利点を生かせていません。このどんどんネストしていく感じ、嫌ですね。

一つ目のAPIを呼ぶところでsubscribeして、その結果の配列をforEachでぶん回して二つ目のAPIをそれぞれの要素に対して実行しています。

accountHttp.getMosaicOwnedByAddress(address)
  .subscribe(mosaics => {
    let mosaicHttp: MosaicHttp = new MosaicHttp();
    
    mosaics.filter(x => x.mosaicId.namespaceId !== "nem")
      .forEach(x => {
        mosaicHttp.getMosaicDefinition(x.mosaicId)
          .subscribe(mosaicDefinition => {
            console.log(x.mosaicId, mosaicDefinition);
            console.log(x.mosaicId, x.quantity / (10 ** mosaicDefinition.properties.divisibility));
          });
      });
  });

修正後

getMosaicOwnedByAddressで流れてくるMosaic配列を、flatMapでバラしてそのまま流します。 流れてきたMosaicfilterをかけてxemを除去します。 xem以外のMosaicを使ってgetMosaicDefinitionを呼び、MosaicMosaicDefinitionを一つのオブジェクトにして流します。 ここをmapで流すとsubscribeの中でさらにsubscribeを呼ぶことになるので、flatMapで流します。

accountHttp.getMosaicOwnedByAddress(address)
    .flatMap(_ => _)
    .filter(mosaic => mosaic.mosaicId.namespaceId !== "nem")
    .flatMap(mosaic => {
      return mosaicHttp.getMosaicDefinition(mosaic.mosaicId)
        .map(mosaicDefinition => <any>{
          mosaicOwnedByTheUser: mosaic,
          mosaicDefinition: mosaicDefinition
        })
    })
    .subscribe(mosaicInformation => {
      console.log(mosaicInformation.mosaicDefinition.id, mosaicInformation.mosaicDefinition);
      console.log(mosaicInformation.mosaicDefinition.id, mosaicInformation.mosaicOwnedByTheUser.quantity / (10 ** mosaicInformation.mosaicDefinition.properties.divisibility));
    });

flatMapをうまく使うことで、二つのAPIコールを一つの流れで処理出来ました。

なんだかすごく(3割ぐらい?w)RxJSが分かった気分になってきました。

Thank you Aleix!