angular
Observable

AngularでGlobal上の外部ライブラリを呼び出してcallbackで戻ってくる方法+Observable

弊社ではangularを使っているのですが、
外部サービスとの連携上、
どうしても

1.angularから外部のライブラリを呼び出す。その際、callbackのメソッド名を指定しておく

2.外部ライブラリは処理完了したら、global上に定義された"1"のcallbackの名前のfunctionを呼び出す

3.global上の定義されたfunctionからangularに戻ってくる

という流れが必要になることがあった。

更に"1"~"3"までの処理をひとまとまりとしてobservableな感じで使いたい。

という場合、以下のようにしたらなんとかなった。

SampleService.ts
declare const window: any; // tslint回避のため

@Injectable()
export class SampleService{
  private isDone = false;
  private response;
  public constructor(...) {
    window.SampleService = this; // thisでglobal上に渡す。
  }

  /**
   * これが目的のメソッド。一旦外部ライブラリになげるが、Observableとして扱いたい。
   */
  public exec(): Observable<...> {
     const params = ...;
     // これが外部提供のライブラリ。 global上に定義された"callbackFunctionName"が呼び出される。
     // 同等のものを自前実装しようかとも思ったが、結構ヘビーだったのと、内部で仕様変更があった時に追随するのが大変なので諦めて使うことにした。
     OtherCompanyLibrary.call(params, "callbackFunctionName");

     return Observable
            .interval(100)
            .timeInterval() // 100ms毎のinterval
            .filter(() => {
                return this.isDone;
            })
            .take(1)
            .map(() => {
                return this.response;
            });
  }

  public callback(response) {
    this.response = response;
    this.isDone = true;
  }
}
index.html
<script>
function callbackFunctionName(response) {
  window.SampleService.callback(response);
}
</script>

windowを介してServiceクラスをやり取りするのと、
Observableのintervalをつかって、処理が完了するのを待つのがポイント。