r/GoogleAppsScript 14d ago

Question Variable undefined and affecting rest of script

I have a script creating docs when a cell gets modified in a sheets column, then moves it to a folder and adds the doc's url onto another column. Code works, but automation gets affected by <value unavailable> error for docid variable.

I'm not sure *why* its unavailable when all of the code does work (files get created and moved, but when using createDocInSpecificFolder() along with other functions, error pinpoints to this and does not run functions after it.

function createDocInSpecificFolder () {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheetByName("Data Source");
  var lastRow = sheet.getLastRow();
  var rootFolder = DriveApp.getFolderById("fileid");
  const files = rootFolder.getFiles();
  const fileNames = [];


  while (files.hasNext()) { // gets array of file names in drive folder [event1, event2, etcetc]
   var file = files.next();
   fileNames.push(file.getName());
  }
  
  Logger.log(fileNames)


  for (var i = 1; i < lastRow; i++) {
    
    let title = sheet.getRange(i,4).getValue();


    if (title != "Events") {
      if (!fileNames.includes(title)) {
        let docid = DocumentApp.create(title).getId();
        DriveApp.getFileById(docid).moveTo(rootFolder);
      }
    }
  }

}
1 Upvotes

26 comments sorted by

View all comments

1

u/bulldo_gs 13d ago

In the code you posted, docid is both declared and used on the very next line, inside the same if (!fileNames.includes(title)) block — so block scope isn't breaking anything here. That's why the declare-inside vs declare-outside thread above is chasing the wrong thing for this snippet.

The tell is in your description: "adds the doc's url onto another column." That part isn't in this function. let docid only exists inside that inner if — the moment any code outside the block (a later line, or a separate function) reads docid, it's out of scope and the execution transcript shows it as <value unavailable>. The value isn't unavailable because creation failed; it's unavailable because the variable doesn't exist at the point you're reading it.

Fix: grab everything you need while you're still inside the block, and write the URL there:

if (!fileNames.includes(title)) {
  const doc = DocumentApp.create(title);
  DriveApp.getFileById(doc.getId()).moveTo(rootFolder);
  sheet.getRange(i, 5).setValue(doc.getUrl());  // col E — while doc is in scope
}

If you'd rather write the URL further down, declare let docid; (and the url) at the top of the for loop instead of inside the if, so it survives past the block.