skip to Main Content

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


  1. 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 explicit const guest = guests[i], and it would have avoided you trying to call length() 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):

    
    function onEdit(e) {
      writeMultipleRows()
    }
    
    
    function writeMultipleRows() {
      const sheetName = 'Sheet1';
    
      const doc = SpreadsheetApp.getActiveSpreadsheet();
      const sheet = doc.getSheetByName(sheetName);
    
      const headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
      var data = getMultipleRowsData(headers);
      var lastRow = SpreadsheetApp.getActiveSheet().getLastRow();
      var range = SpreadsheetApp.getActiveSheet().getRange(lastRow + 1, 1, data.length, data[0].length);
      range.setValues(data);
    }
    
    function getMultipleRowsData(headers) {
    
      var data = [];
    
      const name = "Organizer";
      const email = "[email protected]";
      const phone = "805-555-1234";
    
      const guests = [{
        guestName: "guest1",
        mealChoice: "choice1",
      }, {
        guestName: "guest2",
        mealChoice: "choice2",
      }];
    
      for (const guest of guests) {
        const guest_name = guest.guestName;
        const meal = guest.mealChoice;
        const policy = "some-policy";
    
        // 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 JSON.stringify({ "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;
    }
    
    Login or Signup to reply.
  2. Try this:

    function myfunk() {
      const ss = SpreadsheetApp.getActive();
      const data = { name: "Sheet0", email: "", policy: "on", guests: [{ guestName: "My Name", mealChoice: "salmon" }, { guestName: "Wifes Name", mealChoice: "steak" }] };
      const sh = ss.getSheetByName(data.name);
      let o = data.guests.map(obj => [obj.guestName, obj.mealChoice]);
      sh.getRange(sh.getLastRow() + 1,1,o.length,o[0].length).setValues(o);
      Logger.log(JSON.stringify(o).replace('],','],n'));
    }
    
    Execution log
    11:01:13 AM Notice  Execution started
    11:01:14 AM Info    [["My Name","salmon"],
    ["Wifes Name","steak"]]
    11:01:15 AM Notice  Execution completed
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search