【发布时间】:2020-03-12 12:09:35
【问题描述】:
我有一个 GAS,我在我的 webapp 中提交了一个表单。它执行以下操作:
- 打开一个包含占位符(格式为
##form_field_name##)的模板文档,该占位符对应于表单上的表单域的名称 - 复制模板并将其保存到适当的位置
- 遍历提交的值并执行
body.replaceText('##' + key + '##', val);将值填充到文档中 - 使用
body.replaceText('##.*##', '');删除任何留空字段的占位符字符串(因为它们当前未与表单一起提交)
我最终得到的文档看起来用户根本没有提交任何数据。我的猜测是这是因为 #4 在 #3 完成之前运行。有没有办法将#4 指定为回调?比如:
body.replaceText('##' + key + '##', val, () => {
body.replaceText('##.*##', '');
});
这是执行replaceText()ing 的函数的代码:
/**
* Iterate through obj of keys/values and replace ##key##
* with value in doc
**/
function doFindAndReplace(obj, doc) {
try {
//body = doc.getBody();
var id = doc.getId();
var _doc = DocumentApp.openById(id);
var body = _doc.getBody();
//var doc = _doc;
//Logger.log(body);
for (var prop in obj) {
if(obj.hasOwnProperty(prop)) {
var val = obj[prop];
var key = prop.indexOf('intake') === 0 ? prop.toUpperCase() : '';
//Logger.log(key + ' = ' + val);
//Logger.log(typeof val);
body.replaceText('##' + key + '##', val);
_doc.saveAndClose();
var _doc2 = DocumentApp.openById(id);
body = _doc2.getBody();
body.replaceText('##.*##', '');
}
}
} catch(e) {
Logger.log('doFindAndReplace() | ' + e);
errors.push({
fxn: 'doFindAndReplace',
msg: e,
custom: 'id=' + id
});
return false;
}
return doc;
}
参数obj 是一个包含提交的表单数据的对象,doc 是对正在其中进行查找和替换的新创建文档的引用。
如果不可能的话,我正在考虑添加一个运行#4 (body.replaceText('##.*##', '');) 的onOpen 触发器。这将要求用户在线时首次打开文档,并且很大一部分用例是离线使用新创建的文档。
谁能建议另一种解决方法?
** **编辑** **
我将我的代码(如上所示)更新为“saveAndClose()”,然后在运行第二个“replaceText()”之前重新打开。我收到以下错误:
文档已关闭,其内容无法更新
我知道,你会认为它会出现在 saveAndClose() 之后。但这是错误所在的行,即使我删除了它之后的其余行,也会发生同样的错误。
如果我按原样删除带有代码的saveAndClose() 行,我会再次遇到原来的问题。
我不认为这和Weird Behaviour with DriveApp.getFileById()是同一个问题
** **编辑 2** **
这是传递给函数的对象的示例:
{
intake_activity_level: "Normal",
intake_assessment_comments: "",
intake_client_addr: "1600 Fake St XXXX, XX 12345",
intake_client_email: "xxx@gmail.com",
intake_client_name: "Dan Tester",
intake_client_phone: "(917) 555-1212",
intake_consent: "yes",
intake_consent_owner: "Jim David",
intake_food_intake: "Decreased",
intake_gen_food: "",
intake_gen_health: "sit dolam amet",
intake_gen_meds: "re et sapien et, consectetur rhoncus lacus. Aliqua Vivamus ipsum diam, venenatis a turpis eget, volu",
intake_gen_reasons: "Lorem ipsum",
intake_gen_vaccine: "Yes",
intake_misc_comments: "",
intake_misc_descriptor: "wood",
intake_panting: "Increased",
intake_pet_breed: "Pug",
intake_pet_dob: "8/11/2015",
intake_pet_name: "FLuffy",
intake_pet_sex: "Spayed Female",
intake_pet_species: "Dog",
intake_pet_weight: "140lbs",
intake_sleep: "Increased",
intake_source: "Sally Balls",
intake_stiffness: "Normal",
intake_symptoms: "coughing, belching or gas",
intake_vet: "Urban Vet",
intake_voice: "Increased",
intake_water_intake: "Decreased"
}
可以通过here 访问文档的简化版本。
【问题讨论】:
-
您的问题可能源于最近与表单提交相关的错误。基本上,存在“幻像”提交,其中表单以某种方式自动提交而没有相应的数据。在 stackoverflow 中搜索相关主题,您应该会找到该问题的各种解决方法。
-
没有 GAS 正在接收数据。当我删除
body.replaceText('##.*##', '');时,文档填充得很好。我只需要一种方法来阻止该行运行,直到上一个replaceText()调用完成。 -
GAS 是同步的。你错过了别的东西。你能展示你的完整剧本吗?
-
@Tanaike - 感谢您对此进行调查。是的,
var key = prop.indexOf('intake') === 0 ? prop.toUpperCase()行正在产生所需的结果。没有任何需要的数据被重置为空字符串。带有示例数据的对象以及指向示例文档的链接在我上面的帖子中,位于** EDIT 2 **
标签: google-apps-script web-applications asynccallback