Pavel Varenik
Pavel Varenik

Reputation: 71

How to share map between functions in google app script

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.

Upvotes: 0

Views: 132

Answers (2)

Cameron Roberts
Cameron Roberts

Reputation: 7377

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.

Upvotes: 2

Pavel Varenik
Pavel Varenik

Reputation: 71

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));

Upvotes: 0

Related Questions