7
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【kintone】フィールド値更新でハマりがちなこと

Last updated at Posted at 2020-11-11

こんにちは!
今日は、私がカスタマイズを初めて間もない頃にハマった

「値が表示できないぞ!」

についてです。

別アプリのレコードのデータを使って、フィールド値を更新したいときにハマりがちなところかと思います。
読んでみて、やってみてね!

作りたい目標アプリ

マスターアプリ ドロップダウンで値をとってくる
image.png 1110.gif

|

マスターアプリを作る

マスター?、マスタ?
呼び出し元となるデータを置いとくアプリを作ります。

作り方はかんたん

フィールド種類 フィールドコード
ドロップダウン カテゴリ
文字列(1行) 名前
ドロップダウンの選択肢
文具
おやつ

登録するレコード

カテゴリ 名前
おやつ チョコレート
おやつ プロテイン
文具 鉛筆
文具 消しゴム

↓こんな感じになったらOK

呼び出し側のアプリを作る

フィールド種類 フィールドコード
ドロップダウン カテゴリ(中身はマスターアプリと同じ)
文字列(複数行) 内容

↓こんな感じになったらOK

JavaScriptを書く

それでは、コードを書いていこうと思います。
こちらは呼び出し側アプリのJavaScriptとなります。

フィールド値変更イベントを拾う

↓このあたりを参考に、「カテゴリ」フィールド値変更イベントを拾います。
レコード追加画面のフィールド値変更時イベント
レコード編集画面のフィールド値変更時イベント

↓こんな感じ

(()=>{
    kintone.events.on([
        'app.record.create.change.カテゴリ', //新規・カテゴリフィールド変更イベント
        'app.record.edit.change.カテゴリ' //編集・カテゴリフィールド変更イベント
    ],  event => {
        //ここに処理を書く
        return event;
    });
})();

マスターアプリからレコードを持ってくる

kintone REST API を使って、選択したカテゴリのレコードを一括取得します。
参考:レコードの一括取得(クエリで条件を指定)


        let body = {
            'app': マスターアプリのアプリID,
            //↓これは、ドロップダウンで選択したカテゴリのレコードだけ取ってくるクエリ
            'query':`カテゴリ in("${event.record.カテゴリ.value}")`
        };
        
        //REST API(GET)を叩いて、データを持ってくる
        kintone.api('/k/v1/records', 'GET', body,(resp)=>{
            //ここで持ってきたデータを処理して、内容フィールドに表示する
        });

取得したデータを処理して、内容フィールドに表示する

        kintone.api('/k/v1/records', 'GET', body,(resp)=>{
            let retStr ="";
            //resp.records内の「名前」フィールドを改行挟んで連結している
            resp.records.forEach(r => {
                retStr +=  r.名前.value + "\n";
            });

            //「内容」フィールドに連結した「名前」を表示する
            event.record.内容.value = retStr;
        });

ひとまずコードが出来上がり。

しかし、これだとうまくいきません

(()=>{

    kintone.events.on([
        'app.record.create.change.カテゴリ', //新規・カテゴリフィールド変更イベント
        'app.record.edit.change.カテゴリ' //編集・カテゴリフィールド変更イベント
    ],  event => {

        let body = {
            'app':  マスターアプリのアプリID,
            //↓これは、ドロップダウンで選択したカテゴリのレコードだけ取ってくるクエリ
            'query':`カテゴリ in("${event.record.カテゴリ.value}")`
        };
        
        //REST API(GET)を叩いて、データを持ってくる
        kintone.api('/k/v1/records', 'GET', body,(resp)=>{
            let retStr ="";
            //resp.records内の「名前」フィールドを改行挟んで連結している
            resp.records.forEach(r => {
                retStr +=  r.名前.value + "\n";
            });

            //「内容」フィールドに連結した「名前」を表示する
            event.record.内容.value = retStr;
        });

        return event;
    });
})();

ここ変えよう

この部分が思ったように動かない原因となります。

            //「内容」フィールドに連結した「名前」を表示する
            event.record.内容.value = retStr;

理由は・・・
フィールドにデータをセットする前にevent=>{~}が終わっちゃってるからかな・・・。
kintone.api()が非同期なので。レコードにセットする頃にはイベントが終わっちゃってる。だと思います。
//正しい理由がわかる方いらっしゃったら教えて下さい・・・

kintone.api(~)の中ではget&set使ってみよう!

というわけで、
event.recordに直接書き込むのではなく、get&setをつかいます。

            //「内容」フィールドに連結した「名前」を表示する
            let obj = kintone.app.record.get();
            obj.record.内容.value = retStr;
            kintone.app.record.set(obj);

できあがり

(()=>{

    kintone.events.on([
        'app.record.create.change.カテゴリ', //新規・カテゴリフィールド変更イベント
        'app.record.edit.change.カテゴリ' //編集・カテゴリフィールド変更イベント
    ],  event => {

        let body = {
            'app':  マスターアプリのアプリID,
            //↓これは、ドロップダウンで選択したカテゴリのレコードだけ取ってくるクエリ
            'query':`カテゴリ in("${event.record.カテゴリ.value}")`
        };
        
        //REST API(GET)を叩いて、データを持ってくる
        kintone.api('/k/v1/records', 'GET', body,(resp)=>{
            let retStr ="";
            //resp.records内の「名前」フィールドを改行挟んで連結している
            resp.records.forEach(r => {
                retStr +=  r.名前.value + "\n";
            });

            //「内容」フィールドに連結した「名前」を表示する
            let obj = kintone.app.record.get();
            obj.record.内容.value = retStr;
            kintone.app.record.set(obj);
        });

        return event;
    });
})();

↓こんな感じになりましたでしょうか!?
1110.gif

まとめ

kintone×JavaScriptって、非同期との戦いのことなのかなぁ・・・と思いました。
ちなみに、他のイベント(レコード追加/編集画面の表示後イベントなど)だと、
Promiseオブジェクトをreturnできるので、
getとset使わなくても

return kintone.api(~~~).then(resp=>{
//event.record.内容の値を更新する
return event;
})

で値の更新ができます。
試してみてくださいね!

7
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?