APIトークンを利用してのkintone.apiによるループ処理について

皆様

初めまして。

私は現在、あるアプリにてレコード登録を行う際にAPIトークンを用いて同アプリ内のレコードをGETして、期間が重複しているレコードが無いかチェックを行っているのですが、登録されているレコードが500件以上の場合、ループ処理をしなければなりません。

今まではkintone.proxyのヘッダー部分に{“X-Cybozu-API-Token”: “xxxxx”}と設定を行うことで取得できたのですが、ループするためにkintone.proxyの外側にwhile文などを記載すると、永遠に回り続けてループが終わらなくなってしまいました。

調べてみたところ、kintone.apiにてコールバックを省略するとpromiseオブジェクトが返ってくる処理を利用したもの(この場合のヘッダー情報の設定の仕方はわかりません・・)や、XMLHttpRequestの利用などがあるのですが、この他になにか方法などご存知の方はいらっしゃいますでしょうか?

以下、現在の失敗したソースになります。

kintone.events.on(‘app.record.edit.submit’, function(event) {

var rec = event.record;
var appId = event.appId;
var recId = rec.$id.value;

var loopendflg = false;

return new kintone.Promise(function(resolve, reject) {

var limit = 500;
var loopCount = 0;
var param = {};
var header = {
“X-Cybozu-API-Token”: “xxxxx”,
“Content-Type”: JSON.stringify(“application/json”),
“__REQUEST_TOKEN__”: kintone.getRequestToken()
};

var query = 条件文;
query = encodeURIComponent(query);

var url = kintone.api.url(‘/k/v1/records’, true) + “?app=” + アプリID + “&query=” + query;

while (!loopendflg) {
kintone.proxy(url, ‘GET’, header, param, function(body, status, headers) {
var list = JSON.parse(body).records;

リストを基に条件チェック  
if () {  
 reject(エラーメッセージ);  
 return;  
} else {  
 resolve();  
 return;  
}  

});
}

}).then(function(success) {
return event;
}).catch(function(error) {
event.error = error;
return event;
});

});

以上です、宜しくお願い致します。

g_furuさん
cstapの瀧ヶ平です。

kintone.apiの処理は非同期でかつPromiseを使って行われており通常の同期的な処理と違いwhile文を使うのは好ましくありません。

ご自身で実装するのであれば、while文を使うのではなく、条件を満たしたレコードを全件取得する関数をPromiseによる再帰関数で実装するのが筋ですね。こちらを参考にして実装すると良いかと思います。

あるいはkintone Utility Library for JavaScriptを使って全件取得するのが良いかと思います。

 

g_furuさん

 

 

こんにちは。

非同期処理でループ処理する場合は再帰処理を使うのが一般的です。

すでにkintone.apiで再帰処理によるサンプルがあったので、これをkintone.proxy向けに修正してみました。(動作確認はしていないです

参考:https://developer.cybozu.io/hc/ja/articles/204730600

 

(function() {
 "use strict";

 var header = {
  "X-Cybozu-API-Token": "xxxxx",
  "Content-Type": JSON.stringify("application/json"),
  " __REQUEST_TOKEN__": kintone.getRequestToken()
 };
 var query = 条件文;
 query = encodeURIComponent(query);
 var url = kintone.api.url('/k/v1/records', true) + "?app=" + アプリID + "&query=" + query;

 function fetchRecords(appId, opt_offset, opt_limit, opt_records) {
  var offset = opt_offset || 0;
  var limit = opt_limit || 500;
  var allRecords = opt_records || [];
  var params = {app: appId, query: 'order by レコード番号 asc limit ' + limit + ' offset ' + offset};
  return kintone.proxy(url, 'GET', header, params).then(function(args) {
   var body = JSON.parse(args[0]), status = args[1], header = args[2];

   // error
   if (status !== 200 || status !== 201) {
    throw new Error();
   }

   // success
   allRecords = allRecords.concat(body.records);
   if (body.records.length === limit) {
    return fetchRecords(appId, offset + limit, limit, allRecords);
   }
   return allRecords;
  });
 }

 kintone.events.on('app.record.edit.submit', function(event) {
  return fetchRecords(kintone.app.getId()).then(function(records) {
   console.log('success');
   return event;
  }).catch(function(error) {
   console.log('error');
   event.error = error.message;
   return event;
  });
 });
})();

瀧ヶ平

ご解答ありがとうございます。

>あるいはkintone Utility Library for JavaScriptを使って全件取得するのが良いかと思います。

このようなものがあるとは存じませんでした。

こちら、参考にさせて頂きます。

 

カキ氷

ご解答ありがとうございます。

サンプルまで記載頂き大変有難う御座いました。助かりました。

kintone Utility Libraryと共に試してみようと思います。

 

この度は本当に有難う御座いました。