google-apps-scripttriggersgoogle-docs

Apps Script cannot destructure ScriptProperties field as it is undefined


Running into a ScriptProperties error when trying to follow the guide from this answer (https://stackoverflow.com/a/77856464/29032043)

I can run onOpen and logEverything fine, but get the following error trying to run addView:

Error    
TypeError: Cannot destructure property 'viewers' of 'undefined' as it is undefined.
addView @ Code.gs:11

My current code is below, and I followed the edit script properties instructions for "viewers" as directed. Do I need to add an additional script properties or add a definition for it within the code itself?

const PROP_SERVICE = PropertiesService.getScriptProperties();

const onOpen = () => {
  const email = Session.getActiveUser().getEmail(),
    date = new Date().toLocaleString(),
    viewers = JSON.parse(PROP_SERVICE.getProperty('viewers')),
    user = email.split('@')[0];
  addView({viewers, user, email, date});
};

const addView = ({viewers, user, email, date}) => {
  if (viewers[user]) {
    viewers[user].count++;
  } else {
    viewers[user] = { 
      count : 1, 
      visits : [],
      email
    };
  }
  viewers[user].visits.push(date);
  console.log(`Added view for ${user}`);
  saveView(viewers);
};

const saveView = viewers => {
  PROP_SERVICE.setProperty('viewers', JSON.stringify(viewers));
  console.log('view saved');
};

const logEverything = () => {
  const viewers = JSON.parse(PROP_SERVICE.getProperty('viewers'));

  for (user in viewers) {
    console.log(`User ${user} has visited ${viewers[user].count} time/s with email ${viewers[user].email}.`);
    console.log(viewers[user].visits);
  }
};

I've tried adding quotes around "viewers" within the addView block. Also tried defining user or setting a default value. No change in the result, still sent back an error message saying it is undefined.

Any help would be appreciated - I'm very new to this!


Solution

  • Setting a Property value using setProperty() Method

    There is no instance that the property value of viewers exists and may affect the following code since it will return null.

    To make things work the code needs to be set up for setting property using the setProperty() method.

    function onOpen(){
      let email = Session.getActiveUser().getEmail(),
        date = new Date().toLocaleString(),
        viewers = JSON.parse(PROP_SERVICE.getProperty('viewers')),
        user = email.split('@')[0];
    
        // If the property viewers does not exist it will create the property.
        if(!PROP_SERVICE.getProperty('viewers')){
         viewers = PROP_SERVICE.setProperty('viewers', {});
        }
        
      addView({viewers, user, email, date});
    };
    

    Sample Output:

    10:46:53 PM Info User sample has visited 1 time/s with email sample@email.com.
    10:46:53 PM Info [ '1/3/2025, 10:39:54 PM' ]
    10:46:53 PM Info User sample2 has visited 2 time/s with email sample2@email.com.
    10:46:53 PM Info [ '1/3/2025, 10:46:15 PM', '1/3/2025, 10:46:50 PM' ]
    

    Note: To make this work the document should be share as Editor.

    Reference: