changeイベントで、別のアプリからレコードがある場合に、自分のアプリのルックアップフィールド値を代入したい

何を実現したいのかを書きましょう

新規登録時、入力したテーマNoが参照元にレコードが存在するなら、代入し、
存在しないなら代入しないことがしたいです。
changeイベントだとルックアップフィールド値に値の代入が可能で、
submitイベントだとルックアップフィールド値に値の代入が不可能のようです。
changeイベントにはpromisが対応していないことはわかりますが、ほかに実現方法はないものでしょうか?
どなたか教えていただきたいです。

発生した問題やエラーメッセージを具体的に書きましょう

テーマNo_01はルックアップ設定したフィールド値で、javascript apiのpromiseで参照元のレコード件数があったら、自分のアプリのルックアップフィールドに値を代入したいです。
参照元の件数が0件だったら、ルックアップフィールドをクリアし、空のままで保存させたいです。

実行したコードをコピー&ペーストしましょう

	kintone.events.on(['app.record.create.**change**.テーマNo_'], event => {


		const record = event.record;

		// テーマNoが入力されている場合
		if (record.テーマNo_.value) {

			**record.テーマNo_01.value = record.テーマNo_.value;**
**           event.record['テーマNo_01'].lookup = true;**

		}

		return event;

	});

@rena_168 さん

こんにちは、少しお力になれそうだったので回答させていただきました。
そうですよね、changeイベントでは基本promiseを対応していないのですが、裏技的な方法がございまして…

以下に @rena_168 さんのコード利用させていただいてサンプル書かせていただきますね。

kintone.events.on(['app.record.create.**change**.テーマNo_'], event => {


		const record = event.record;

		// テーマNoが入力されている場合
		if (record.テーマNo_.value) {

			**record.テーマNo_01.value = record.テーマNo_.value;**
**           event.record['テーマNo_01'].lookup = true;**

             //↓このように即時関数で実行すればエラーになりません。
             (async () => {
                const body = {
                    app: kintone.app.getId(),
                    id: 1,
                }
                const resp = await kintone.api(kintone.api.url('/k/v1/record.json', true), 'GET', body);
                console.log(resp);
             })();

		}
		return event;
	});

このように、async即時関数で囲めば実行できるようになるので、恐らくされたい事として実現できるのではないかなと考えております。

「いいね!」 1

すみません、async/awaitもchangeイベントでつかえないと書いてあり、
(フィールド値変更イベントで、他のアプリのフィールドの値を書き換えたい - Legacy_Account399 の #4)
実際JSEdit for kintoneでエラーになっております。


いかがでしょうか。

JSEditではエラーとでるかもしれないですが、実際動かしてみてコンソールログ見てみると即時関数内ではasymc/awaitでも動いていませんか?
こちらの環境ではchangeイベントでも動いていますが…

「いいね!」 1

おっしゃってる通り、自分のアプリをGETできてはいますが、bodyの中は参照元の別のアプリから取得してみると、デバッグでエラー「Uncaught (in promise) Object」が出ました。
やっぱり難しいものなんでしょうか。。。

情報を同じアプリから取得するのと、違うアプリから取得するのは、REST API上何も違いがないはずですので、先ほどのサンプルで動いているなら動くと思っていますが…
動かないコードはって頂いてもいいですか?

以下が実際のソースですが、自分のappは169で別の参照先のappは168です。
特別に難しいことはしていませんが、エラーが出ております。
宜しくお願いします。

kintone.events.on(['app.record.create.change.テーマNo_'], event => {


	const record = event.record;

	// テーマNoが入力されている場合
	if (record.テーマNo_.value) {
  var resp = "";
  //↓このように即時関数で実行すればエラーになりません。
   (async () => {
      const body = {
        'app': 168,
        'query': `テーマNo_= "${record.テーマNo_.value}"`
      }
      resp = await kintone.api(kintone.api.url('/k/v1/record.json', true), 'GET', body);
      console.log(resp);
   })();
         
    if (resp.record.length > 0) {  
			record.テーマNo_01.value = resp.record.テーマNo_.value;
          event.record['テーマNo_01'].lookup = true;
      
    }

	  
	  
	}
	return event;

なるほどですね…とりあえず見当たるところとして、
queryを使う場合は、URLを

'/k/v1/record.json' => '/k/v1/records.json'

recordsに変える必要がありますね :sweat_drops:

あと加えて、queryの内容も = などと スペース噛ませておいた方が可読性あがりますね :sweat_drops:

「いいね!」 1

あぁ、そうでしたね!
ありがとうございます。

しかし、理解できないところが、return event後にapi実行のところが実行されているようです。そのため、詳細画面上に「保存」ボタンを押す必要があるようです。
何でこんなふうになるものでしょうか。

if (record.テーマNo_.value) {
//↓このように即時関数で実行すればエラーになりません。
(async () => {
const body = {
‘app’: 168,
‘query’: テーマNo_= "${record.テーマNo_.value}"
}
const resp = await kintone.api(kintone.api.url(‘/k/v1/records.json’, true), ‘GET’, body);
console.log(resp);
if (resp.records.length > 0) {
record.テーマNo_01.value = resp.records[0].テーマNo_.value;
event.record[‘テーマNo_01’].lookup = true;

      }
   })();
         

	  
	return event;

	}

changeイベントの中に非同期処理を入れないで普通にルックアップ設定のフィールドには値が設定できるのに、非同期処理を入れると代入されないのです。

根本的に何かが違うものでしょうか。

簡単にイベント発火からのフローをまとめてみると、

チェンジイベント発火!

同期処理

async即時関数 → await処理 → 終了

return event;でチェンジイベント終了

という風にチェンジイベントで起きた処理とasync即時関数で起きた処理は同期しなくなるんですね…
そのため、チェンジイベントでreturn eventしても反映されない!ということが起きます。

そのため、ほぼ答え書いてしまって申し訳ないですが、以下のようにしてあげる必要があると思います。
こちら試してなく素で書いただけなので、試してみてエラーがでたら適時変更してみてください。

kintone.events.on(['app.record.create.change.テーマNo_'], event => {
    const record = event.record;

    // テーマNoが入力されている場合
    if (record.テーマNo_.value) {
        var resp = "";
        //↓このように即時関数で実行すればエラーになりません。
        (async () => {
            const body = {
                'app': 168,
                'query': `テーマNo_= "${record.テーマNo_.value}"`
            }
            await kintone.api(kintone.api.url('/k/v1/record.json', true), 'GET', body).then((resp) => {
                console.log(resp);
                const rec = kintone.app.record.get();
                if (resp.records.length > 0) {
                    rec.record.テーマNo_01.value = resp.records[0].テーマNo_.value;
                    rec.record['テーマNo_01'].lookup = true;
                } else {
                    rec.record['テーマNo_01'].lookup = 'CLEAR';
                }
                kintone.app.record.set(rec);
            });
        })();
    }
    return event;
})

コード解説としては、GETメソッドを.then()のメソッドチェーンで待ってから、
kintone.app.record.get()で取得

ルックアップの処理分岐

kintone.app.record.set()でレコードに反映
って感じですね。
詳しくは

「いいね!」 2

先輩、ありがとうございます!
get,setは初めて使用します。
今まではpromiseでやってきて、うまくいってるのに今回はできないはずがないと思いましたが、実装し方も色々あるんですね!
とても勉強になりました!!!

「いいね!」 1

先輩なんて恐縮です :sweat_drops:
そうですね、結構いろんな実装方法ありますけど、こんな感じで一歩一歩処理がつかめるようになれば、あとは肌感でなんとかなること多いですよ :sweat_smile:
また、機会がございましたら宜しくお願いいたします!

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