kintoneのJavaScriptカスタマイズでは、様々なイベントハンドラを利用してアプリの挙動を拡張します。これらのイベントハンドラ内で使用されるEventオブジェクトをイミュータブル(変更不可)に扱うことでバグを減らすことができます。
ミュータブルなコードとは
例
例えば下記のようなコードは、どのタイミングでも値の変更をゆるすことで、ミュータブルに値を扱っていることになります。
// イベントハンドラ
kintone.events.on('app.record.create.submit', (event) => {
const record = event.record;
record.fieldCode.value = 123; // 数値フィールドを変更
return event;
});
問題点
パット見るとなにも問題ないようにみえますが、上記のようにeventで渡ってくるコードを直接書き換えてしまうと、ハンドラの中身が長くなったときにどうコードを変更したかがわからなくなり、 バグの温床になります。
間に、ミュータブルにレコードを操作する関数があると最悪で、いつどのように値が変わったかが追えなくなり、非常にやっかいなコードになります。
// イベントハンドラ
kintone.events.on('app.record.create.submit', (event) => {
const record = event.record;
record.fieldCode.value = 123; // 数値フィールドを変更
// いくつかの処理をかく
// ここで、オリジナルのデータを想定した処理をかいてしまう
if(record.fieldCode.value > 100) {
// 省略
}
return event;
});
イミュータブル(変更不可)なコードで表現する
例1
上記の例ですと、下記のように表現ができます。
structuredClone というオブジェクトのコピーをする関数があり、それを利用して、新しいレコードを先につくります。
// イベントハンドラ
kintone.events.on('app.record.create.submit', (event) => {
const newRecord = structuredClone(event.record);
const newRecord.fieldCode.value = 123; // 数値フィールドを変更
// 省略
// 最後に書き換え
event.record = newRecord;
return event;
});
例2
関数を作るときも、常に新しいオブジェクトを返すようにする(直接書き換えないようにする)ことでバグを減らすことができます。
// イベントハンドラ
kintone.events.on('app.record.create.submit', (event) => {
const newRecord = structuredClone(event.record);
// 省略
// 最後に書き換え
event.record = addValue(record, 10);
return event;
});
function addValue = (record, value) => {
const newRecord = structuredClone(event.record);
newRecord.fieldCode.value = Number(newRecord.fieldCode.value) + value;
return newRecord;
}
補足
少しでもイミュータブルに始めれるとよいですが、下記のように毎回新しい値を作るのが理想です。基本的には上書きをせず、値を新たに定義していくイメージです。
最後に使っているのはスプレッド構文というものです。
// イベントハンドラ
kintone.events.on('app.record.create.submit', (event) => {
const record = event.record;
// 処理Aをしたレコード
const executedARecord = funcA(record);
// 処理Aのあと処理Bをしたレコード
const executedBRecord = funcB(executedArecord);
// 結果
const result = {
...event,
record: executedBRecord;
}
return result;
});