プラグイン開発をしていると、プラグインに「Search for Things」で検索したテーブルデータをそのまま渡したい!なんてことないでしょうか。
でも中身のデータの取り方がわからない…と以前諦めていました。
今回お仕事で、データの更新ログを保存するときに、レコードをJSONに直せないかな?と検索したのがきっかけで、プラグインに「Search for Things」の値を渡し、中身をJSON化してみました!
とりあえずプラグインを作る
早速ですがプラグインを作ります。ここでは適当にjsonなんて名前にしました。
ActionsタブでClient sideのアクションを作成します。
テーブルデータを受け取るには、Fields Typeは「any thing」にし、listにチェックします。
とりあえずデータの中身を見たい
そもそも、データがどのように渡されているのかを確認したいです。JSONでないことは、JSON.stringify(フィールド)とすればわかります。
いったん、Action codeに以下を書きました。
function(properties, context) {
//Load any data
let len = properties.field1.length();
let field1 = properties.field1.get(0, len);
console.log(JSON.stringify(field1))
}
適当なアプリにインストールし、ページ読み込み時にアクションを実行します。
プレビューして、コンソールを確認します。
何かいることはわかりますね…。
ではここでJSON.stringifyをしないで field1をそのままコンソールに書き出してみます。
function(properties, context) {
//Load any data
let len = properties.field1.length();
let field1 = properties.field1.get(0, len);
console.log(field1)
}
コードを書き換えて再度プレビュー!
f(e)となっているので、関数になっていることがわかりました。
ここでAction codeのドキュメントを見ると、以下のような記載が。
currentUserデータは、get(フィールド)で値を取得できる。フィールドはlistProperties()で取得できる。
先ほどのコンソールの結果と同じ関数なので、フィールド名を取得してみます。
function(properties, context) {
//Load any data
let len = properties.field1.length();
let field1 = properties.field1.get(0, len);
// フィールド名
let keyArray = field1[0].listProperties()
console.log(keyArray)
}
テーブルのデータなので、構造は何行目でも同じなので、1行目のlistPropertiesを取得して表示してみます。
キタキター!(テンション爆上げ)😆
それっぽいものが取得できました!進みそうな予感。
リレーションでないカラム
リレーションでないカラムのプロパティ名は以下のようになっているようです。
カラム名_フィールドタイプ
リレーションのカラム
リレーションのカラムは、先ほどfield1の中身をコンソールに書き出した通り、getとlistPropertiesの関数になっています。
Itemテーブルでは、companyカラムがcompanyテーブルとリレーションを貼っており、companyテーブルは私が作ったテーブルなので以下のようなプロパティ名になっています。
カラム名_custom_テーブル名
取得したフィールド名を指定して中身を見る
それでは、取得したプロパティ名をget()の引数に指定し、テーブル内の{プロパティ名:値}というJsonを作ってみます。
function(properties, context) {
//Load any data
let len = properties.field1.length();
let field1 = properties.field1.get(0, len);
// フィールド名
let keyArray = field1[0].listProperties()
let json = [];
field1.map( function(data, index){
let arr = {};
keyArray.forEach(function(element){
arr[element] = data.get(element)
})
json.push(arr)
} )
console.log(JSON.stringify(json))
}
プレビューするとこんな感じ。
[
{
"company_custom_company": {},
"name_text": "item1",
"price_number": 80,
"Created By": {},
"Slug": null,
"Created Date": "2022-02-06T16:15:47.656Z",
"Modified Date": "2022-03-11T13:09:33.967Z",
"_id": "1644164147656x160951553785273480"
},
・・・・
]
見事にリレーションがあるデータが取得できていません。
個別にリレーションがあるフィールドをコンソールに書き出してみるとわかるのですが、値がテーブルデータの場合 get()、listProperties() の関数が入っています。
つまり入れ子になっているんですね。
ここで、テーブルデータの場合はひたすらlistProperties()を取得し中身をJson化する、を繰り返そうかと思ったのですが…Created Byの値がUserテーブルで、プロパティの中身を全部取得するとやっぱりCreated Byが存在し、無限ループになることに気づきました。
ItemレコードのCreated By(作成者)のCreated By(作成者)のCreated By…..
ということで、結論として、1階層だけlistProperties()を書き出し、この中でまたテーブルデータが指定されている場合はスキップ、ということにしました。
最終的なコード
さて、いきなりですが結果のコードです。JavaScriptがわからないとしんどいです。エキスパートでなくても大丈夫です。
function(properties, context) {
//Load any data
let len = properties.field1.length();
let field1 = properties.field1.get(0, 1);
// フィールド名
let keyArray = field1[0].listProperties()
field1のプロパティ名を取得
//Do the operation
let json = [];
let obj = '[object Object]';
field1.map( function(data, index) {
let arr = {};
keyArray.forEach(function(element){ 取得したプロパティ名に対し
let el = data.get(element); elにデータを格納
let toString = Object.prototype.toString;
if (toString.call(el) === obj){ elがオブジェクトの場合
console.log(el)
if(el.hasOwnProperty('listProperties')) {
listPropertiesというプロパティを持っている場合=テーブルデータ
console.log(element + ':Thing')
let keyArr = el.listProperties();
もう1回プロパティを取得
let ob = {};
keyArr.forEach(function(item){
if(el.get(item) && !el.get(item).hasOwnProperty('listProperties')) ob[item] = el.get(item);
})
arr[element] = ob
jsonに格納
}else if(el.hasOwnProperty('get')){
elがオブジェクトで、getのみ持つ場合=配列
console.log(element + ':Arr')
arr[element]= el.get(0,el.length())
配列をjsonに格納
}
}else{ elがオブジェクトでない場合は値をそのまま
arr[element] = data.get(element)
}
});
json.push(arr)
});
console.log(JSON.stringify(json))
}
とりあえずこんな感じです。(確認用コメントのコンソールが残ってます)
get(プロパティ名)が配列なのか、テーブルのデータなのか、は1つ1つコンソールに書き出してみると法則性が掴めてきます。
こちらのプラグインのエディタを見て解析しました。
結果のコンソール
[
{
"company_custom_company": {
"address_text": "埼玉県越谷市赤山町2-2-3",
"name_text": "アーク株式会社",
"Created Date": "2022-03-08T15:18:05.693Z",
"Modified Date": "2022-03-08T15:18:05.701Z",
"_id": "1646752685693x181110378739317570"
},
"name_text": "item1",
"price_number": 80,
"Created By": {
"Created Date": "2021-08-24T13:42:23.858Z",
"Modified Date": "2021-08-24T13:42:23.858Z",
"_id": "admin_user_アプリ名"
},
"Slug": null,
"Created Date": "2022-02-06T16:15:47.656Z",
"Modified Date": "2022-03-11T13:09:33.967Z",
"_id": "1644164147656x160951553785273480"
},
.....
]
こんな感じでテーブルデータが書き出しできました。
いやぁなかなか長かった…。
このデータ構造さえわかれば、テーブルデータをプラグインに渡して、プラグイン内で色々とできそうですね。