I have a GAS that i'm submitting a form in my webapp to. It does the following:
##form_field_name##
) corresponding to the names of the form fields on the formbody.replaceText('##' + key + '##', val);
to populate the values into the docbody.replaceText('##.*##', '');
to get rid of the place holder strings for any fields left blank (as they are not currently submitted with the form)I'm ending up with a document that looks like the user did not submit ANY data at all. My guess is that it's because the #4 is running before #3 finishes. Is there any way to specify #4 as a callback? Something like:
body.replaceText('##' + key + '##', val, () => {
body.replaceText('##.*##', '');
});
Here is the code for the function that does the 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;
}
The parameter obj
is an object containing the submitted form data and doc
is a reference to the newly created document in which the find-and-replace is taking place.
If nothing like that is possible, I was thinking about adding an onOpen
trigger that wold run the #4 (body.replaceText('##.*##', '');
). This would require that the user opens the doc for the first time while online and a huge part of the use case is using the newly creatted document offline.
Can anyone suggest another workaround?
Document is closed, its contents cannot be updated
I know, you'd think it would come after the saveAndClose()
. But thta's the line the error points at and even if I remove the rest of the lines after it, the same error occurs.
If I remove the saveAndClose()
line with the code as is, I get my original problem again.
I don't think this is the same issue as Weird Behaviour with DriveApp.getFileById()
{
intake_activity_level: "Normal",
intake_assessment_comments: "",
intake_client_addr: "1600 Fake St XXXX, XX 12345",
intake_client_email: "[email protected]",
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"
}
and a watered-down version of the Document can be accessed here.
'##' + key + '##'
to va;
with body.replaceText('##' + key + '##', val);
using obj
.##.*##
to ''
with body.replaceText('##.*##', '');
.body.replaceText('##.*##', '');
after all body.replaceText('##' + key + '##', val);
were run.If my understanding is correct, how about this answer?
In your current script, body.replaceText('##.*##', '');
is put in the for loop. By this, only intake_activity_level: "Normal",
is used and other objects are not used. In this case, after the 1st body.replaceText('##' + key + '##', val);
is run, all ##key##
values are removed by body.replaceText('##.*##', '');
. I thought that this might be the reason of your issue.
When your script is modified, please modify as follows.
From: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('##.*##', '');
}
}
To:
for (var prop in obj) {
if(obj.hasOwnProperty(prop)) {
var val = obj[prop];
var key = prop.indexOf('intake') === 0 ? prop.toUpperCase() : '';
body.replaceText('##' + key + '##', val);
}
}
body.replaceText('##.*##', '');
body.replaceText('##' + key + '##', val);
is run in the for loop. And then, body.replaceText('##.*##', '');
is run at the outside of the for loop.saveAndClose()
is required, how about putting doc.saveAndClose()
after body.replaceText('##.*##', '');
?