やろうとしていたこと
配列データをfor文で処理し、中身に応じて、ダイアログを2,3回出して、最後の処理まで終わったら、次の配列要素の処理でまたダイアログを2,3回出して、といった処理をループさせようとしていた。
エラーの内容と原因の推測
エラーメッセージとしては
「Dialog with id exists already the dialog id must be unique」
であり、下記の現場証拠がありました。
- エラーメッセージからして、おそらく何個もダイアログ出そうとしてるが、一個ずつしか出せないために起きているエラー
- ダイアログ内にはタイトルやメッセージを渡していたのだが、その内容が配列の最後の要素の内容だった
- 配列の要素が一つの場合はエラーがでない。
これらの現場証拠から、同期的に処理できてないため、ダイアログをいくつも表示してしまうことで起きているエラーだと推測しました。
原因となっていた箇所
awaitが効いていない状態でした。
抜粋にになりますが、下記のように記述していましたが、同期的に処理が出来ていませんでした。
・問題のあった実装(抜粋)
//定義側
showDialogFunc(){
const dialogRef = this.dialog.showDialog();
dialog.afterClosed().subscribe(()=>{
// 閉じた後の処理
})
}
//呼び出し側
await this.showDialogFunc();//ここのawaitが効いてなかった。
理由
ダイアログの返り値がobservableだったためでした。冷静に考えれば、subscribeを使っている時点でsubscriptionを返すのでawaitが効かないのは当然の結果かもしれません。
(afterClosed()はObservableを返します。)
打ち手
返り値がpromiseになるようにfirstValueFromでpromiseオブジェクトに変換してやって、同期的に処理するようにしました。
//修正前
showDialogFunc(){
const dialogRef = this.dialog.showDialog();
dialog.afterClosed().subscribe(()=>{
// 閉じた後の処理
})
}
//修正後
showDialogFunc(){
const dialogRef = this.dialog.showDialog();
const ret = await firstValueFrom(dialog.afterClosed());
if(ret === okBtn){
//閉じた後の処理
}
}
参考にした記事