外部APIより取得したデータを現在のレコードの登録する方法

1.背景・実現したいこと

お世話になっております。

テキストフィールドの値が更新されたときに、外部のAPIから取得し、その情報を編集画面のフィールドに反映したいと考えています。

情報の取得と、eventオブジェクトへのデータの登録までは確認できていますが、セットしたデータがレコード上に反映されません。

 

  1. ソースコード kintone.events.on([‘app.record.edit.change.BNrecordID’,‘app.record.create.change.BNrecordID’],function(event){
        
        ~中略~
        
          function getBNLead() {
          return new kintone.proxy(‘https://xxxxxxxxxxxxxxxxxxxx’, ‘GET’, requestHeader, {}).then((resp) => {
            // success
            respRecord = JSON.parse(resp[0]);
            return respRecord;
          }, (error) => {
            // error
            console.log(error); // proxy APIのレスポンスボディ(文字列)を表示
          });
          };

      getBNLead().then(
      response => {
        event.record.family_name.value = response[‘lead’][‘family_name’];//取得したデータをレコードに設定
        event.record.first_name.value = response[‘lead’][‘given_name’];
        return event; //←ここがうまく動いていない?
      },
      error => {
        console.log(“エラー”);
      }
      );
    });

 

3.エラー情報

特にエラーは表示されません。

return event;が動作していない?

changeイベントで非同期処理を含む場合、eventオブジェクトを編集する形での値変更はできません(非同期処理の完了を待つことはできません)。その場合はレコードの値を取得するレコードに値をセットするが必要です。

        event.record.family_name.value = response['lead']['family_name'];//取得したデータをレコードに設定
        event.record.first_name.value = response['lead']['given_name'];

let recordData = kintone.app.record.get(), rec = recordData.record;

      rec.family_name.value = response['lead']['family_name'];
      rec.first_name.value = response['lead']['given_name'];

kintone.app.record.set(recordData);

出来ました。早速のご回答ありがとうございます。

eventオブジェクトが使えないのではという疑いは持っていて、次のコードも試しておりました。

kintone.events.on([‘app.record.edit.change.BNrecordID’,‘app.record.create.change.BNrecordID’],function(event){
           ~中略~
      function getBNLead() {
      var recordData = kintone.app.record.get();
      return new kintone.proxy(‘https://xxxxxxxxxxxxxxxxxxxx’, ‘GET’, requestHeader, {}).then((resp) => {
           ~以下略~

 

You cannot call kintone.app.record.get() in handler or during processing a handler.というエラーが出るためこの方法はだめだと思っていたのですが、kintone.app.record.get()が非同期処理内では使用できるのはどういう理屈なのでしょうか?
kintone.appの仕様と理解すればよいでしょうか。

gotoTAT さま

changeイベントにはPromiseがなく、またイベントハンドラ内か、イベントハンドラ外かの違いです。

      function getBNLead() {
/* ここはイベントハンドラ内(return eventする前なので、kintone.app.record.get()を実行すると「イベントハンドラ内では使用できない」というエラーが発生します) */
      return new kintone.proxy('https://xxxxxxxxxxxxxxxxxxxx', 'GET', requestHeader, {}).then((resp) => {
    /* ここはイベントハンドラ外(return eventした後なので、eventオブジェクトはありません) */

プログラムは原則上から順に実行していきますが、非同期処理はその順ではなく、then()以降の処理(kintone.proxyを実行し、その成功を確認してからの処理)が実行されるのはかなり後になります。kintone.proxyはあくまで「サーバーに対してAPIを実行する」までが実行文で、実行するという処理が終わったため、その結果を待たずに次の処理に移ってしまいます。

Promiseが使用できる他のイベント(showやsubmit)ではこれを待ってからreturn event(イベントの終了)をすることができますが、changeイベントでは待つことができないので、then()以降の処理が実際に実行されるのはreturn eventの後になります。

return event後にフィールドに反映するためには、kintone.app.record.set()が必要、という理屈です。

 

この辺りの説明はうまくできる自信がないので微妙ですが、参考になれば幸いです。

mls-hashimoto様

なるほど、eventオブジェクトを使えるようにすると処理の完了を待つことになり、そもそも非同期処理自体が成り立たないということですね。

非常に勉強になりました。

ありがとうございます。

このトピックはベストアンサーに選ばれた返信から 3 日が経過したので自動的にクローズされました。新たに返信することはできません。