ObservableをSubscribeした時にハマったこと


HttpClientのGETメソッドから値をsubscribeする

Angularでとあるデータをバックエンドから呼び出し、それをフロントエンドで処理して描画する必要があったのですが、

ユーザーが条件入力 $\Rightarrow$ データをAPIから呼び出す $\Rightarrow$  データを処理して描画する

という流れから、データを処理するためにはデータのロードが終わっていなければいけませんでした。じゃあどこなら確実にロードが終わっているのか?という疑問の答えを探すのに苦労しました。

Subscribeの流れ

例えばこんな感じのGETメソッドをsubscribeするとします。

//get-dataService.ts

getAll(): Observable<DataObject> {
    return this.http.get('somegreatURL');
  }
ngOnInit(): void {

    this.getDataService.getAll().subscribe(datas =>{
      this.datas = datas;
    });

  //ここでconsole.log(this.data);をしてもthis.datasを初期化していなければundefined, していれば初期値が返ってくる
}

コード内のコメントの通り、subscribeの直後にデータを受け取るはずの変数を確認しても、ロードが完了していません。では何が順番におきるのか?

  1. コンポーネントが初期化をして、getDataServiceのgetAll()を呼び出します
  2. getAll()はObservableを返します
  3. 返ってきたObservableに対してsubscribeをコールします
  4. その後初めてリクエストがサーバーへ送られます
  5. ngOnInit()の実行が完了

ここでお気づきかと思いますが、まだリクエストを送っただけなのでデータが返ってきてません。データが返ってくるときの処理を見ましょう。
上記の流れの後に、サーバーの処理が終わったら次の処理が行われます。

1.getAll()にデータが返されます
2.コンポーネントのsubscribe内のdatasに値が送られます
3.コンポーネント内で宣言したthis.datasにデータを格納します

つまりデータが確実に格納されるのはthis.datas=dataの行の後ということになので、簡単に同期的処理をさせるのであればそこで処理を行えば少なくとも予期してない処理を行わなくて済みます。

ただし基本的に非同期処理のメリットを潰すことになりますので、データのローディングを他の処理は待たなければなりません。他に良い方法があればコメントいただければ幸いです。

参考にしたサイト