レコードの更新でたまに失敗することがあります

お世話になります。

現在、カレンダー表示で表示用フィールド(文字列)を用意してレコード編集および追加成功イベントにおいて

表示用の文字列を作成しスケジュール表のような物を作成しています。

その中で下記動作を実行しておりますがPUTで稀に失敗することがあります。

 

恐らくPrimiseの記述が正しくなくPUTの処理よりも先にレコード登録が済んでしまっている為だと考えているのですが

Promiseを分けて記述したりallなどのTip等も参考に順次処理の作成を試みてみましたが正しく動作するような記述ができずに困っております。

どうかご助言いただけないでしょうか。

 

フィールドから値を取得

RESTAPI でカテゴリを取得

表示用に取得データをつなぎ合わせる

表示用データをPUTする

レコード詳細の表示を省く画面遷移処理

 

//カテゴリ取得
return new kintone.Promise(function(resolve, reject) {
kintone.api(kintone.api.url(‘/k/v1/record’, true), ‘GET’, body, function(resp) {
category = resp.record.カテゴリー.value;

//表示用文字列の作成
var displ = {

“app”: appId,
“id”: ev.recordId,
“record”: {
//チェックボックス等の選択、文字列フィールドなどから表示文字列を作成

}
};

//レコード更新
kintone.api(kintone.api.url(‘/k/v1/record’, true), ‘PUT’, displ, function(resp) {
}, function(error) {
});

resolve(ev);
}, function(error) {
resolve(ev);
});

//画面遷移処理

Shinohara さん

kintone.api は、非同期処理のため kintone.api の完了を待たずに画面遷移処理が開始されます。

画面遷移処理と rest api を同時に処理しているようなものですので、タイミングによって kintone.api が失敗すると思われます。

画面遷移処理を kintone.api 完了後に行ってみてください。

 

あと全体のコードが無いため不明なところがありますが、

もし追加・編集レコードと同じレコード内の表示用文字列を更新しているのであれば rest api を使わず、

レコード追加・編集画面の保存実行前イベントで「フィールドの値を書き換える」がつかえると思います。

ただし表示用文字列内に、レコード番号がある場合は rest api による更新が必要です。

 

rex0220 さん 

はじめまして。ご返信ありがとうございます。

説明不足で申し訳ございません。

表示用フィールドはユーザー側では不要なので見えないようsetFieldShown=falseにしていて

非表示ではフィールドを直接編集する操作が行えない為、登録後のレコードを編集できるrest apiを使用しています。

 

kintone.api完了後に行うよう以下のように変更してみたのですが

未知のエラーにより思うように動作が得らません。

どこか使い方が間違っている箇所はございますでしょうか?

 

kintone.events.on(‘app.record.edit.submit.success’, function(ev) {
var record = ev.record;
//フィールドから情報を取得

var displ;

var category;
var body = {
‘app’: appId,
‘id’: ev.recordId
};

//カテゴリ取得
var Getfunc = new kintone.Promise(function(resolve, reject) {
kintone.api(kintone.api.url(‘/k/v1/record’, true), ‘GET’, body, function(resp) {
category = resp.record.カテゴリー.value;

//カテゴリやフィールド値から表示用文字列の作成

resolve():
}, function(error) {
reject(error);
}); //kintone.api(GET)
}); //Promise(GET)

//レコード更新
var Putfunc = new kintone.Promise(function(resolve, reject) {
kintone.api(kintone.api.url(‘/k/v1/record’, true), ‘PUT’, displ, function(resp) {

resolve();

}, function(error) {

reject(error);
}); // kintone.api(PUT)
}, function(error) {
reject(error);
}); //Promise(PUT)

return kintone.Promise.all([Getfunc,Putfunc]).then(function(results){
//遷移処理
return ev;
}); // Promise.all
}); //event

 

 

Shinohara さん

今度のコードでは、GET と PUT の処理が同時に動きます。

GET 完了後に PUT 処理を行いましょう。

>非表示ではフィールドを直接編集する操作が行えない為

項目が非表示であっても、「フィールドの値を書き換える」がつかえますよ。

非表示は、ブラウザー上で単に見えなくしているだけです。

こちらにした方が簡単です。

 

どうしもPUTで書き換えたいなら下記でいけるはずです。

 

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

    var record = ev.record;

    //フィールドから情報を取得

    var displ;

    var category;

    var body = {

        ‘app’: appId,

        ‘id’: ev.recordId

    };

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

        kintone.api(kintone.api.url(‘/k/v1/record’, true), ‘GET’, body, function (resp) {

            category = resp.record.カテゴリー.value;

            //カテゴリやフィールド値から表示用文字列の作成

            resolve();

        }, function (error) {

            reject(error);

        }); //kintone.api(GET)

    }).then(function(){

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

            kintone.api(kintone.api.url(‘/k/v1/record’, true), ‘PUT’, displ, function (resp) {

                resolve();

            }, function (error) {

                reject(error);

            });

        }).then(function(){

            //更新に成功後の処理(画面遷移かな?)

        }).catch(function(){

            console.error(“更新に失敗したぜ”);

        });

    }).catch(function(){

        console.error(“取得に失敗したぜ”);

    });

}); //event

rex0220様

返信が遅くなり申し訳ありません。

kintone.apiを使用する必要がないのであればその方がコードが簡単になり良いかと私も思います。

私の勘違いのようですので時間がある時に直接フィールド値を書き換えて編集できるように変更したいと思います。

 

からに様

 

ご提示いただいたコードが現状に近いのでひとまずこちらで実装して

おかげさまでPromiseを使用してエラーなく動作しました。

また、頂いたコードを参考にPromiseの使い方について理解も深まりました。誠にありがとうございます。

 

eventオブジェクトのスコープ範囲についての理解が少しあいまいなので質問させて下さい。

画面遷移についてはev.urlに指定してevent returnにより行っておりましたが

ご提示いただいたコードの中に記載するとうまくreturnできていないようでしたが

.then(function())コード内ではイベントオブジェクトはスコープ外なのでしょうか?

(今回は条件分岐によるリダイレクトではない為submitイベント直後にurl指定しました)

無事解決できましたのでご報告です。

 

 

画面遷移を実装する際にurlプロパティの指定を参考にしておりましたが

保存前イベントの役割をちゃんと理解できていなかったことで

その時に実行される処理を全て保存後イベントで実装し

kintone.apiを使用する状況に至っていたようです。

 

最終的にrex0220様にご提案頂いた方法でも実装することができました。

ありがとうございました。