テーマを変更中で、表示が崩れているところがあります…!

【bubble】プラグイン開発中の小話 – Search for Thingsの中身を紐解いてみた

.bubble
.bubble

プラグイン開発をしていると、プラグインに「Search for Things」で検索したテーブルデータをそのまま渡したい!なんてことないでしょうか。

でも中身のデータの取り方がわからない…と以前諦めていました。

今回お仕事で、データの更新ログを保存するときに、レコードをJSONに直せないかな?と検索したのがきっかけで、プラグインに「Search for Things」の値を渡し、中身をJSON化してみました!

とりあえずプラグインを作る

早速ですがプラグインを作ります。ここでは適当にjsonなんて名前にしました。

ActionsタブでClient sideのアクションを作成します。

Client sideのアクションを作成

テーブルデータを受け取るには、Fields Typeは「any thing」にし、listにチェックします。

Field を作成

とりあえずデータの中身を見たい

そもそも、データがどのように渡されているのかを確認したいです。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))
}

適当なアプリにインストールし、ページ読み込み時にアクションを実行します。

作成したアクションにItemデータを渡す
Itemの中身

プレビューして、コンソールを確認します。

コンソール

何かいることはわかりますね…。

ではここでJSON.stringifyをしないで field1をそのままコンソールに書き出してみます。

function(properties, context) {
  //Load any data 
    let len = properties.field1.length();
    let field1 = properties.field1.get(0, len);

    console.log(field1)
}

コードを書き換えて再度プレビュー!

fieldsの中身

f(e)となっているので、関数になっていることがわかりました。

ここでAction codeのドキュメントを見ると、以下のような記載が。

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を取得して表示してみます。

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"
	},
.....
]

こんな感じでテーブルデータが書き出しできました。

いやぁなかなか長かった…。

このデータ構造さえわかれば、テーブルデータをプラグインに渡して、プラグイン内で色々とできそうですね。

タイトルとURLをコピーしました