Search code examples
google-apps-scriptweb-applications

How can I get the active user before the rest of the client-side function runs in Apps Script?


As it is, the function runs, the data set is built, but the user shows as null and that is probably because the client-side function continues running without waiting for the piece below to return the data.

const user = google.script.run.withSuccessHandler(function(user) {
console.log('User: ' + user);
}).getUser();

So, how can I make savePO() wait for the user returned, so that it builds the data set correctly?

function savePo() {
  const table = document.querySelectorAll("#tableRows tr")
  let tableData = [...table].map(r => {
    let td = r.querySelectorAll("td");
    return [...td].map((c, j) =>
      j == 9 ? c.querySelectorAll('input[type="checkbox"]')[0].checked :
      j == 8 ? c.innerText :
      c.querySelector('input').value)
  });

  let timeStamp = new Date();
  timeStamp = timeStamp.toString();
  const user = google.script.run.withSuccessHandler(function(user) {
  console.log('User: ' + user);
  }).getUser();
  const notes = document.getElementById('notes').value;

  tableData.forEach(function(row) {
    row.unshift(supplier, buyer, billTo, notes);
    headerData.forEach(function(el) {
      row.unshift(el);
    })
    row.push(timeStamp, user);
  })
  console.log('Complete Table Data: ' + JSON.stringify(tableData)) //Returs all, but user is null
}

PS: Don't mind how terrible it may look - best practice wise. Learning What first, then I'll improve how as I go.


Solution

  • Simply move your google.script.run outside of savePo and call it from within the success handler callback function. Let say someEventHandler is associated with a button on your HTML page. Now getUser() is called first to get the user. When it finishes it calls savePo(user).

    function someEventHandler() {
      google.script.run.withSuccessHandler(function(user) {
        savePo(user);
      }).getUser();
    }
    
    function savePo(user) {
      const table = document.querySelectorAll("#tableRows tr")
      let tableData = [...table].map(r => {
        let td = r.querySelectorAll("td");
        return [...td].map((c, j) =>
          j == 9 ? c.querySelectorAll('input[type="checkbox"]')[0].checked :
          j == 8 ? c.innerText :
          c.querySelector('input').value)
      });
    
      let timeStamp = new Date();
      timeStamp = timeStamp.toString();
      const notes = document.getElementById('notes').value;
    
      tableData.forEach(function(row) {
        row.unshift(supplier, buyer, billTo, notes);
        headerData.forEach(function(el) {
          row.unshift(el);
        })
        row.push(timeStamp, user);
      })
      console.log('Complete Table Data: ' + JSON.stringify(tableData)) //Returs all, but user is null
    }