0

I want to create a map when google sheets document opened. So I'm using onOpen() function and create the map. Then I want to use this map in other functions. So I'm using in onOpen():

var documentProperties = PropertiesService.getDocumentProperties();
documentProperties.setProperty("map", map);

and trying to get it in my function:

var x = PropertiesService.getDocumentProperties().getProperty('map'); 

but x is {} and when I'm trying to x.get() it throws error PropertiesService.getDocumentProperties(...).getProperty(...).get is not a function As I understand, PropertiesService can't store the map or I'm doing it wrong. So the question is: how can I create a map on startup and share it between functions. And example:

  var map = new Map();
  maap.set("key1", "value"); 
  maap.set("key2", "value"); 
  documentProperties.setProperty("map", map);
  var x = PropertiesService.getDocumentProperties().getProperty('map');
  var y = PropertiesService.getDocumentProperties().getProperty('map').get('key1'); 

P.S. values in my map are maps too.

Pavel Varenik
  • 71
  • 1
  • 7

2 Answers2

2

The property service only stores Strings. Anything you wish to store in a property must be converted to a string first.

In this case, you can do this with JSON, and and the entries() method on the Map object.

First, get the Map entries with the entries() method, convert the entries to a simple array, and then convert the resulting array to a JSON string before storing it.

Next, retreive the JSON string, parse it back into an Array, and pass that Array to the constructor of a new Map().

Be aware there is a relatively small upper limit on property values, if you are storing a very large (or steadily growing) map of data, you might want to explore another way of storing the data, such as in the cells of a Google Sheet, or in an external database using JDBC.

Cameron Roberts
  • 7,127
  • 1
  • 20
  • 32
  • Thank you for the right direction. But map.entries() is an iterator and it doesn't work. But I found a solution here https://stackoverflow.com/questions/29085197/how-do-you-json-stringify-an-es6-map `documentProperties.setProperty("map", JSON.stringify(map.entries(), replacer)); var map = new Map(JSON.parse(documentProperties.getProperty("map"), reviver));` – Pavel Varenik Mar 18 '21 at 19:56
  • Ah interesting, I was not even aware Javascript had introduced the concept of iterators. I have removed the inaccurate code from my answer to avoid confusion. – Cameron Roberts Mar 18 '21 at 20:34
0

The right answer is here by Pawel

function replacer(key, value) {
  if(value instanceof Map) {
    return {
      dataType: 'Map',
      value: Array.from(value.entries()), // or with spread: value: [...value]
    };
  } else {
    return value;
  }
}
function reviver(key, value) {
  if(typeof value === 'object' && value !== null) {
    if (value.dataType === 'Map') {
      return new Map(value.value);
    }
  }
  return value;
}

...


documentProperties.setProperty("map", JSON.stringify(map.entries(), replacer));
var map = new Map(JSON.parse(documentProperties.getProperty("map"), reviver));
Pavel Varenik
  • 71
  • 1
  • 7