I am trying to append multiple rows to my google sheet all at once, but every time I try, I only append one row.
My data comes from my website’s rsvp form. In that form each person can rsvp up to a certain amount of people based on their invitation. So for example, I would be RSVP-ing for both myself and my wife.
The form data stored (and that I send to my appscript) looks like this
{"name":"sheet test","email":"","policy":"on","guests":[{"guestName":"My Name","mealChoice":"salmon"},{"guestName":" Wife’s Name","mealChoice":"steak"}]}
The data is sent to the appscript using fetch
fetch(url, { method: "POST",
headers: {
'Content-Type': 'application/json'
},
body: formDataJSON })
.then(function (response) {
if (response.ok) {
// redirectToConfirmationPage(formData);
console.log("Yay it worked!");
} else {
throw new Error("Error submitting form.");
}
})
.catch(function (error) {
console.error(error);
alert("Error submitting form. Please try again later.");
});
}
My goal is to append X rows to my appscript where X is the number of guests.
The schema of the table looks something like this:
Date, form_data, name, guests, policy, meal, phone, email
Where form_data is the entire stringified data from the form, and guests are stored by name under guests. So the date, form_data, name, policy, phone, and email should all be the same for anyone filling out the form for multiple people.
I don’t know if I am handling it correctly. Instead of appending each row one at a time, I am creating a larger data set, then adding all of the data all at once to a range.
Right now though, I can’t even test it properly because I keep getting
Sorry, unable to open the file at this time.
Please check the address and try again.
Does anyone know what this error is? I logged out of all of my other accounts and made the app script accessible to anyone, so I don’t know why this would be happening. My theory was that it wasn’t working before because of the multiple deployments, but now it doesn’t work at all
For reference here is the app script code as well
function doPost(e) {
try {
writeMultipleRows(e)
return ContentService.createTextOutput("Thanks for submitting!" + JSON.stringify(formyData));
} catch (e) {
console.error(e);
return ContentService.createTextOutput('Error: ' + e.message);
} finally {
lock.releaseLock();
}
}
function writeMultipleRows(e) {
const sheetName = 'thesheetname';
const scriptId = 'immadeletethislol';
const doc = SpreadsheetApp.openById(scriptId);
const sheet = doc.getSheetByName(sheetName);
const headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
var data = getMultipleRowsData(e, headers);
var lastRow = SpreadsheetApp.getActiveSheet().getLastRow();
var range = SpreadsheetApp.getActiveSheet().getRange(lastRow + 1, 1, data.length, data[0].length);
range.setValues(data);
}
function getMultipleRowsData(e, headers) {
var data = [];
const formData = e;
const name = formData.name;
const email = formData.email;
const phone = formData.phone;
const guests = formData.guests;
const policy = formData.policy;
for (var i = 0; i < guests.length(); i++) {
const guest_name = guest["guestName"];
const meal = guest["mealChoice"];
// Create an array representing the values for this guest
var guestData = headers.map(header => {
if (header === 'Date') return new Date();
if (header === 'form_data') return String({ "Form Data": "form_data" }); // Include the entire form data
if (header === 'name') return name;
if (header === 'email') return email;
if (header === 'phone') return phone;
if (header === 'guests') return guest_name;
if (header === 'policy') return policy;
if (header === 'meal') return meal;
return '';
});
data.push(guestData)
}
return data;
}
Thanks!
So far I have tried appending rows both all at once and one at a time, but I keep getting just one row.
I removed all of the other emails I signed into.
I also removed all of my old deployments and archived them, but since then, the run hasn’t worked at all (I get the following error)
Sorry, unable to open the file at this time.
Please check the address and try again.
2
Answers
There are several syntax errors here that you need to address before even getting to the root of the problem. I suggest using the AppsScript debugging tool to help you. From what I can see:
1.
for (var i = 0; i < guests.length(); i++) {
You should probably not iterate using an iterator like this. Try instead a for/of or .forEach():
for (const guest of guests) {
In any case, this would have avoided you missing defining
guest
(you would need an explicitconst guest = guests[i]
, and it would have avoided you trying to calllength()
as a function (it is a property).2. Not a mistake, just a style suggestion, but in .js there’s no reason to use a string accessor for a known property:
const guest_name = guest["guestName"];
becomes
const guest_name = guest.guestName
;3. If you get these sorted, probably the root of your issue is that you are only getting the first row back from your function.
In this:
var range = SpreadsheetApp.getActiveSheet().getRange(lastRow + 1, 1, data.length, data[0].length);
You get
data[0].length
, which is only getting the first guest’s length (which if it’s an object, I think that’s a syntax error). You need to get the whole length of the array and use that to calculate your range.Here’s a self-contained test example of this working (note that I’m using JSON.stringify() here as well, otherwise you’ll just get [object Object] in each cell):
Try this: