0

I'm trying to add to an array when a dropdown button is pressed but app-script seems to redeclare the array everytime an event is triggered. is there a way to stop this?

the code in question looks like this:

let by = [];
function addToArray (name = 'hello') {
  by.push(name.replace(/\s[\s\S]*/, '').toLowerCase());
  console.log(by.join(', '))
}

//  ...

// function called every dropdown buttonclick
function handelAdd () {
  const response = DocumentApp.getUi().prompt('Name:'); // prompt that gets name of item added
  if (response.getSelectedButton() == DocumentApp.getUi().Button.OK) {
    add(response.getResponseText());
  }
}

1 Answer 1

2

I am going to assume that the following line in the question, here:

add(response.getResponseText()); // incorrect?

Should actually be this:

addToArray(response.getResponseText()); // correct?

Whenever your script finishes execution, any state it had saved (for example the value of the array in let by = [];) is lost.

This is to be expected. The script has finished. It exits. The document is still open, but the script has completed its work. It will run again the next time there is a relevant button click event.

To save state between multiple runs of the script, you can use Properties Services. This allows you to store a variable associated with the specific document (and user of that document). You can save your list to this storage, and retrieve it when you need to add a new item to it.

But you also need to store your array of data as a string in this storage - so in my example below I will convert the [...] array to a JSON string representation of the array, using JSON.stringify(). And I will convert back from JSON to an array using JSON.parse():

let by = [];

let byList = 'BY_LIST';

function addToArray (name = 'hello') {
  let userProps = PropertiesService.getUserProperties();
  // retrieve stored list and convert back from JSON to array:
  by = JSON.parse(userProps.getProperty(byList));
  console.log(by);
  by.push(name.replace(/\s[\s\S]*/, '').toLowerCase());
  userProps.setProperty(byList, JSON.stringify(by));
  console.log(by.join(', '))
}

//  ...

// function called every dropdown buttonclick
function handelAdd() {
  const response = DocumentApp.getUi().prompt('Name:'); // prompt that gets name of item added
  if (response.getSelectedButton() == DocumentApp.getUi().Button.OK) {
    addToArray(response.getResponseText());
  }
}

// used for my testing:
//function testMe() {
//  handelAdd();
//}

function onOpen(e) {
  // whenever the doc is re-opened, set the list to be 
  // empty, and store it in userProperties as a JSON string:
  let userProps = PropertiesService.getUserProperties();
  userProps.setProperty(byList, JSON.stringify( [] ));
}

The onOpen() trigger ensures that each time the document is opened, we start with a new empty list.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.