Dev Study
← Angular コース

44. asyncパイプ — 購読と解除をAngularに任せる

asyncパイプは、Observableをテンプレートで直接受け取るための仕組みです。{{ user$ | async }} のように書くと、Angularが裏でsubscribeして値が届くたびに表示を更新し、コンポーネントが破棄されるときには購読の解除まで自動で行ってくれます。@if (users$ | async; as users) の形にすれば、届いた値に users という名前を付けてブロック内で使い回せます。

実務では「APIから取得した値をそのまま表示するだけ」の場面がとても多く、そのたびに手動でsubscribeして状態に詰め替えるのは手間です。asyncパイプならコンポーネントにはObservableのプロパティを1つ置くだけで済み、コードが大幅に短くなります。手動subscribeで起きがちな「解除忘れによるメモリリーク」が構造的に起きないのが最大の利点です。

つまずきやすいのは、asyncパイプを使うにはコンポーネントの imports に AsyncPipe を追加する必要がある点です。また、値が届くまでは null が返るため、@if で「まだ届いていない状態」を分けて扱うのが定番です。同じObservableに asyncパイプを何か所も付けると購読がその数だけ走るので、as構文で1回受けて使い回しましょう。

サンプルコード(フレームワーク環境が必要なため表示のみ)

import { Component, inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { AsyncPipe } from '@angular/common';

type User = { id: number; name: string };

@Component({
  selector: 'app-user-list',
  imports: [AsyncPipe],
  // as構文で1回だけ受けて users という名前で使い回す
  template:
    '@if (users$ | async; as users) {' +
    '  @for (user of users; track user.id) { <p>{{ user.name }}</p> }' +
    '} @else { <p>読み込み中...</p> }',
})
export class UserListComponent {
  private http = inject(HttpClient);

  // subscribe は書かない。購読も解除も async パイプに任せる
  users$ = this.http.get<User[]>('/api/users');
}
サンプルコードで身につける(5本) →

学んだ概念を、素朴な例から実務寄りの例まで5つの具体例で確認します。

公式ドキュメントで詳しく ↗