
オブジェクトから不要なプロパティを一括削除する関数が、APIのPOSTで大活躍?
今日も元気にノンプロ研でGAS勉強中です。
最近freee API講座を受講してAPIでデータを取得したりできるように(少し)なりました。
ただ、取得に関しては色んなサービスがcsv出力を提供しているので、やはり醍醐味としてはPOST(=データを登録)するですよね。
ここで立ちはだかるのがPOST(=データを登録)するためのデータ形式を整えるところ。具体的にはJSON形式のオブジェクトを作らないとなのですが、これが複雑。
講座でも「JSONデータを一から作るのは難しい」と紹介されていました。
GETリクエストでテンプレートとなるJSONデータを取得し加工しよう
そこで紹介されたのが、まず一度サンプルとなるJSONデータをGET(=データの取得)で1件取得して、そのJSONデータを解析して、不要なプロパティを削除して、新しいPOST(=データを登録)用のJSONのテンプレートを作ろうというアプローチです。
step1:直近の明細を1件取得
step2:step1で取得したデータを加工
step3:step2で加工したデータを登録
ふむ、頭いい。
オブジェクトから不要なプロパティを一括削除する関数に挑戦
しかし、基本ものぐさな私。この解析を毎回様々なデータでやるのか…と思うと気が滅入ります。
さらにはAPIで扱うJSONデータというと、オブジェクトの中にオブジェクトがあったり、オブジェクトの中に配列、さらに配列の中にオブジェクトと多重入れ子構造になっていて、解析が大変です。
ということで、オブジェクトから不要なプロパティを一括削除する関数を作れないかと悪戦苦闘の結果、なんとか形にできました。
/**
* オブジェクトからテンプレートのキー一覧との共通しないプロパティを削除する関数
* @params {object} obj 元となるオブジェクト
* @params {array} temKeys 残したいテンプレートオブジェクトのキー一覧
* @return {object} obj 共通しないキーのプロパティを削除したオブジェクト
*/
function deleteDiffProperties_(obj, tempKeys) {
const keys = Object.keys(obj);
// テンプレートのキー一覧との共通しないキーの一覧を配列で取得
const diffKeys = keys.filter(key => !tempKeys.includes(key));
// 共通しないキーのプロパティを削除
diffKeys.forEach(difKey => delete obj[difKey]);
return obj;
}
原材料として用意するのは
・GET(=データの取得)してきたオブジェクト
・リファレンスなどで確認したPOST(データの登録)に必要なキー項目の一覧を配列に格納したもの
です。
const keys = Object.keys(obj);
で、オブジェクトのキー一覧を配列で取得
const diffKeys = keys.filter(key => !tempKeys.includes(key));
が、今回のハイライトですが、tempKeys(残したいキー一覧)に含まれない差分のキーのみを一覧にしてdiffKeys(different keys)に格納しています。
filter()メソッドは、配列の全ての要素に対して個々に、()内の関数を実行にして、そのテストに合格した要素から新しい配列を作ってくれます。
今回は「!」をつけてtempKeys(POST用の必要なキー一覧)に key(=オブジェクトがもともと持っているプロパティのキー項目)が含まれるかを判定するincludes()メソッドを逆転させて、POSTに不要なキーのみを一覧にしました。
diffKeys.forEach(difKey => delete obj[difKey]);
そして最後にGET(=データの取得)してきたオブジェクトから、この不要なキーをdelete演算子で削除していってます。
forEach() メソッドは、配列の各要素に対して、()内で指定した関数を一度ずつ実行するメソッドですね。戻り値が不要な時=関数で処理だけを行いたい時に便利です。
これで意気揚々とPOST(=データを登録)しようとしたのですが、もう一つ障害が…
値がnullや空白のプロパティも削除しなくてはいけなかった
これはfreee APIの場合ですが、POST(=データを登録)してよいプロパティでも値がnullや空白だとエラーが出てしまいました。
ということで、値がnullや空白のプロパティを削除する関数も作りました。
/**
* オブジェクトから値がnullや空のプロパティを削除する関数
* @params {object} obj 元となるオブジェクト
* @return {object} obj 値がnullや空のプロパティを削除したオブジェクト
*/
function deletBlankProperties_(obj) {
Object.keys(obj).forEach(key => {
if (obj[key] === null) { delete obj[key] };
if (obj[key] === '') { delete obj[key] };
})
return obj;
}
ここでもforEach() メソッドが活躍していますね。
基本的には、
1. オブジェクトから不要なプロパティを一括削除する関数
2. 値がnullや空白のプロパティを削除する関数
は合体させても良いかなと思っていますが、色々と挙動を確認するために、今は別々のままテストしています。
めちゃくちゃ興奮しています
この関数たち、記事ではさらっと書きましたが、実務上はめちゃくちゃ使える関数なので、これが作れたことでかなりハッピーな気持ちになっています。
1年前には、コードを自力で書いたこともなかった私でも、コミュニティラーニングの力で、日々の自分のお仕事に使えるコードが書けるようになりました。
ノンプロ研オススメです。