出来事
最近、kintoneでプラグインを複数作成しているが、毎回configの保存でエラーを吐いてしまっていた。
Usage: kintone.plugin.app.setConfig(config, opt_callback)
理由がわからないがJSON.stringify()
をがむしゃらに使うと解決することが多かったです。
今回、この原因を調べて記事にしてみました。
はじめに
kintoneプラグイン開発において、ユーザーが設定した値を保存する場合、単純なテキスト値だけでなく、複雑なデータ構造(配列やオブジェクト)を扱う場面が多々あります。特に複数の設定項目を持つプラグインでは、これらのデータをどのように保存し、どう読み込むかが重要になります。
この記事では、kintoneプラグインの設定画面で複雑なデータ構造を扱う方法、特に JSON.stringify()
を活用した保存方法について解説します。
kintone Plugin APIの制約
kintoneプラグインの設定を保存する際に使用する kintone.plugin.app.setConfig()
メソッドには、重要な制約があります:
このメソッドは単純なキーと値のペアの連想配列(オブジェクト)しか受け付けません。
これは以下のようなデータ構造なら問題なく保存できることを意味します:
// OK: 単純なキーと値のペア
const config = {
appId: "123",
fieldCode: "title",
isEnabled: "true" // 文字列として保存
};
しかし、以下のような複雑なデータ構造は直接保存できません:
// NG: 配列やネストされたオブジェクトを含む
const config = {
appId: "123",
fieldCode: "title",
settings: [
{ field: "field1", value: "value1" },
{ field: "field2", value: "value2" }
]
};
JSON.stringifyを使った解決方法
この制約を解決するための基本的なアプローチは、配列やオブジェクトなどの複雑なデータ構造を JSON.stringify()
を使って文字列に変換して保存することです。
保存時の実装例
// 保存したいデータ構造
const settings = [
{ field: "field1", value: "value1", isVisible: true },
{ field: "field2", value: "value2", isVisible: false }
];
// 設定オブジェクトを構築
const saveConfig = {
appId: "123",
fieldCode: "title",
settings: JSON.stringify(settings) // 配列を文字列に変換
};
// kintone Plugin APIで保存
kintone.plugin.app.setConfig(saveConfig, function() {
alert("設定を保存しました");
// リダイレクト処理など
});
この方法により、複雑なデータ構造を文字列として保存することができます。
読み込み時の実装例
保存した設定を読み込む際は、文字列から元のデータ構造に戻す必要があります:
// 設定を取得
const config = kintone.plugin.app.getConfig(PLUGIN_ID);
if (config) {
// 単純な値は直接取得可能
const appId = config.appId;
const fieldCode = config.fieldCode;
// 文字列化されたデータは JSON.parse() で元に戻す
let settings = [];
try {
settings = JSON.parse(config.settings || '[]');
} catch (error) {
console.error('設定の解析に失敗:', error);
}
// 以降の処理で settings 配列を使用
console.log(settings);
}
実装する際の注意点
1. 例外処理を適切に行う
JSON.parse()
は不正な JSON 文字列に対して例外をスローするため、try-catch ブロックで例外処理を行うことが重要です:
try {
const settings = JSON.parse(config.settings || '[]');
// 成功時の処理
} catch (error) {
console.error('JSONパースに失敗:', error);
// エラー時のフォールバック処理
const settings = [];
}
2. 型の判定も行う
プラグインの更新などで設定の形式が変わる可能性を考慮し、型チェックも行うと安全です:
const settings = typeof config.settings === 'string'
? JSON.parse(config.settings)
: (Array.isArray(config.settings) ? config.settings : []);
3. デバッグ用のログ出力
開発中は設定オブジェクトの内容を確認できるよう、デバッグ用のログ出力を行うと便利です:
console.log('保存する設定オブジェクト:', saveConfig);
console.log('設定オブジェクトの型:', typeof saveConfig);
console.log('JSON文字列化:', JSON.stringify(saveConfig));
実際のコード例
以下は、複数のフィールド設定を持つプラグインの設定保存処理の具体例です:
// 保存ボタンの処理
document.getElementById("js-save-button").addEventListener("click", function () {
// 基本設定の取得
const appId = document.getElementById("app-id").value.trim();
const fieldCode = document.getElementById("field-code").value.trim();
// バリデーション
const errorMessages = [];
if (!appId) {
errorMessages.push('・アプリIDは必須です');
}
// 複数の設定項目を収集
const fields = [];
$('.setting-item').each(function () {
const name = $(this).find('.name-field').val().trim();
const code = $(this).find('.code-field').val().trim();
const isVisible = $(this).find('.visibility-toggle').prop('checked');
if (name && code) {
fields.push({
name,
code,
isVisible
});
} else if (name || code) {
errorMessages.push('・項目「' + (name || code) + '」の情報が不完全です');
}
});
// エラーがあれば表示して処理中断
if (errorMessages.length > 0) {
alert('以下のエラーを修正してください:\n\n' + errorMessages.join('\n'));
return;
}
// 設定オブジェクトの構築
const saveConfig = {
appId: appId,
fieldCode: fieldCode,
// 複雑なデータ構造は文字列化して保存
fields: JSON.stringify(fields)
};
// デバッグ用
console.log('保存する設定オブジェクト:', saveConfig);
// 設定の保存
kintone.plugin.app.setConfig(saveConfig, function () {
alert("設定を保存しました");
window.location.href = '../../' + kintone.app.getId() + '/plugin/';
});
});
また、設定を読み込む部分は次のようになります:
// 既存の設定を読み込む
const config = kintone.plugin.app.getConfig(PLUGIN_ID);
if (config) {
// 基本設定の読み込み
$('#app-id').val(config.appId || '');
$('#field-code').val(config.fieldCode || '');
// 複雑なデータ構造の読み込み
try {
// 文字列からオブジェクトに戻す
const fields = typeof config.fields === 'string'
? JSON.parse(config.fields)
: [];
if (fields && fields.length > 0) {
// 最初の項目を設定
$('.setting-item:first').find('.name-field').val(fields[0].name || '');
$('.setting-item:first').find('.code-field').val(fields[0].code || '');
if (fields[0].isVisible) {
$('.setting-item:first').find('.visibility-toggle').prop('checked', true);
}
// 追加の項目があれば、それぞれ新しい行を作成して設定
for (let i = 1; i < fields.length; i++) {
// 設定行を追加する処理
addSettingRow(fields[i]);
}
}
} catch (error) {
console.error('設定の読み込み中にエラーが発生:', error);
}
}
よくあるエラーと対処法
1. "Usage: kintone.plugin.app.setConfig(config, opt_callback)"
このエラーは、setConfig()
に正しくないパラメータを渡した場合に発生します。
原因の例:
- 設定オブジェクト全体を
JSON.stringify()
してしまった - 設定オブジェクトではなく配列を渡した
解決策:
- 設定オブジェクトは単純なキーと値のペアのオブジェクトとして渡す
- 複雑なデータのみを
JSON.stringify()
する
// NG
const settings = {...};
kintone.plugin.app.setConfig(JSON.stringify(settings), callback);
// OK
const settings = {
key1: value1,
key2: JSON.stringify(complexValue)
};
kintone.plugin.app.setConfig(settings, callback);
2. 設定の読み込みで値がundefinedになる
原因の例:
- 保存時と読み込み時で、キー名が一致していない
- 新しいバージョンのプラグインで設定構造を変更した
解決策:
- キー名の一貫性を保つ
- バージョン間の互換性のための移行コードを用意する
// 移行コードの例
if (config.oldKey && !config.newKey) {
config.newKey = config.oldKey;
}
まとめ
kintoneプラグイン開発において複雑なデータ構造を扱う場合の基本は以下の通りです:
-
複雑なデータ構造は文字列に変換して保存する
-
JSON.stringify()
を使用 - オブジェクト全体ではなく、複雑なプロパティのみに適用
-
-
読み込み時は文字列をデータ構造に戻す
-
JSON.parse()
を使用 - 例外処理を忘れない
-
-
デバッグ情報を活用する
- 保存前の設定オブジェクトの内容と型をログ出力
これらの方法を使うことで、kintoneプラグイン設定で複雑なデータ構造を安全に扱うことができます。プラグインの機能が複雑になるほど、設定データの管理も重要になってきます。適切な設計と実装で、メンテナンス性の高いプラグインを開発しましょう。