Auraコンポーネント: 非同期処理の際はライフサイクルに気をつけようという話
はじめに
AuraコンポーネントからApexのアクションをコールする際に、Promiseを利用し汎用の非同期メソッドを実装しました。
then()を使ったメソッドチェーンで、レスポンス取得後の処理がうまく行きませんでした。
- 非公開属性の
aura:attributeの値が変更されない e.force:closeQuickActionでモーダルが閉じない
該当コード
doAction: function(component, event, helper) { // Apexアクションのコール helper.callAction(component, 'c.getMessage', null) // resolve .then(function(result){ // レスポンスの値をを非公開属性に設定 component.set('v.result', result); // モーダルを閉じる(クイックアクション) $A.get('e.force:closeQuickAction').fire(); }) // reject .catch(function(error){ console.error(error); }) }
原因
Promiseを利用した際、ライフサイクルからはずれてしまうため、コンポーネントへのアクセスに失敗するようです。
Promise はその resolve 関数と reject 関数を非同期に実行するため、コードは Lightning イベントループおよび通常の表示ライフサイクルの外側に存在します。
出典: *1
コールバックが $A.getCallback() でラップされないまま渡されると、コンポーネントの非公開属性にアクセスしようとしたときにアクセスチェックに失敗します。
出典: *2
対策
コールバックを $A.getCallback() でラップします。
出典: *3
以上。
$A.getCallback()でラップすることで、フレームワークのライフサイクルでキャッチできるようになります。
修正後のコード
doAction: function(component, event, helper) { // Apexアクションのコール helper.callAction(component, 'c.getMessage', null) .then( // resolve $A.getCallback(function(result) { // レスポンスの値をを非公開属性に設定 component.set('v.result', result); // モーダルを閉じる(クイックアクション) $A.get('e.force:closeQuickAction').fire(); }), // reject $A.getCallback(function(error) { console.error(error) }) ); }
参考
所感
- 公式ドキュメントはよく読もう(反省)