課題
Javascriptにおいて、nullとundefinedはど扱っていけばいいのか。ということは考えていきたい。
nullとundefinedの詳細な違いはこちらを見ればわかるだろう。
注目ポイント
Angularは、webアプリケーションで、結局はviewとして表現していくために存在するもの。nullとundefinedもその観点において違いを書いてみる。
undefinedの使い方
undefinedは何もない状態である。この何もないというのは、実行時に値がないということだけではなく、永続機関から取得するものがないということである。Angularでおなじみの、AngularFirestoreを使って例を出す。
コード例と説明
getByID$(account_id: string) {
return this.firestore.collection<Account>('accounts').doc<Account>(account_id).valueChanges();
}
上記のvalueChanges()で返される型は、Observable<Account | undefined>
である。undefinedは、angular firestoreのdataを検索したときに、データベースに存在しなかったときに返される。このように、永続期間にデータとして存在しない時にundefinedを使うという事をしたほうがよい。
nullの使い方
undefinedは何もない状態である。この何もないというのは、実行時に値がないということだけではなく、永続機関からまだ値が返ってこないということである。わかりやすくいうと、Loading状態である。Angularでおなじみの、AngularFirestoreを使って例を出す。
コード例と説明
const account$ =
return this.firestore.collection<Account>('accounts').doc<Account>(this.account_id).valueChanges();
}
<component [account]="account$ | async"></component>
typescript上で定義されたObservableをasync pipe(詳しくはこちら)を通してcomponentに値を流すことで、初期値はnull状態になる(詳しくはこちら)。つまり、componentのaccountは、Observable<Account> | undefined | null>
となる。初期値がnullになることで、Loading状態を作り出す事ができるのである。
使い分けのメリット
Componentの状態を細かく出し分けする事ができる。現代のアプリケーションでは、UXが重要項目の一つにあり、一つのUIでも、UIStack(詳しくはこちら)を定義していかねばならない(はず)。非同期データを扱うUIになると、データがない状態、Loading中であるStackを表現することは必須となる。上記の使い分けをすることで、それぞれのStackのUIを一つのComponentに閉じ込める事ができ、非常に保守性の高いアプリケーション開発を行う事ができるのである。
例
値を取得
const account$ =
return this.firestore.collection<Account>('accounts').doc<Account>(this.account_id).valueChanges();
}
親Component
<component [account]="account$ | async"></component>
子Component
<ng-container *ngIf="account; else noValue">
<account></account>
</ng-container>
<ng-template #noValue>
<!---永続期間にデータが存在しなかった時に表示-->
<ng-container *ngIf="account === undefined; else loading">
<not-found></not-found>
</ng-container>
<!---Loading中の時に表示--->
<ng-template #loading>
<loading></loading>
<ng-template>
</ng-template>
まとめ
以上は私が実際にアプリケーションを開発をしてきた上で整理された事項である。また、必ずしも正しくはなく、nullとundefinedの使い分けも千差万別かと思われる。何かしらの参考になれば幸いである。