LoginSignup
6
4

More than 3 years have passed since last update.

【Angular】あなたのasync pipeは {{ 安全 | async }}ですか?

Posted at

aysnc pipeとは

PromiseやObservableな非同期オブジェクトをそのままtemplateで表示できるようにしたpipeで
コンポーネントが破棄される時に自動でunsubscribeしてくれる便利なものです。

アンチパターン

oya.page.html
<div>
 親の中で子コンポーネントを呼ぶ
  <app-kodomo [name]="name$ | async">
   私が子コンポーネントです。
  </app-kodomo>
</div>

親コンポーネントでObservableな値を子コンポーネントに渡す

oya.page.ts

name$ = new BehaviorSubject('Hello');

子コンポーネント側でnullを考慮せずに処理している

kodomo.component.ts

@Input() name:string;

ngOnInit(){
 this.name.slice(0, 1);
}

この場合、実行時エラーがでることがあります。

例として、子コンポーネントに渡すときの話をしましたが
以下のように親側でnullを考慮せずに表示しようとする場合も実行時エラーが発生することがあります。

oya.html
   <div>
      {{ name$.slice(0, 1) | async}}
   </div>

原因

AsyncPipeは購読したObservableが最初の値を流す前に、必ず一度 null を返すようにできているからです。

もとのObservableが Observable だったとしても、 AsyncPipeを通すと State | null となってしまいます。

対処方

  • *ngIf や *ngForでnullをガードする
oya.html
   <div *ngIf="name$ | async as name">
      {{ name.slice(0, 1) | async}}
   </div>

  • 子コンポーネント側でnullを考慮した実装をする(これするくらいならAsyncPipe使わない方がいいです。)

参考資料

lacolacoさん
https://blog.lacolaco.net/2020/02/async-pipe-initial-null-problem/

Angular質問箱
https://youtu.be/LVa68EI9NSw?t=990

6
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
4