Home > Enterprise >  Iterator error when trying to save Google Doc to subfolder in Shared Drive (Apps Script)
Iterator error when trying to save Google Doc to subfolder in Shared Drive (Apps Script)

Time:07-29

I have a code that creates a Google Doc from data on a sheet using a template. After creation, I want that document to save into a specific subfolder on a Shared Drive that I have editor access to.

Specifically, I have it check for the person's name {{Name}} which is row[3] in the sheet. I then have it check for the month {{Month}} which is row[2] in the sheet, and it's supposed to save within the month subfolder. However, my problem is that I keep getting the error Exception: Cannot retrieve the next object: iterator has reached the end. It works for the first NAME folder and then breaks for all after that.

I searched stackoverflow for this issue because it is a common one. It seems that my code is missing hasNext() function to actually perform the iteration. However, I can't figure out how to add this to my code (I am a newbie). I've tried several variations of while and if statements but they always throw various errors.

Here is my current code WITHOUT the hasNext(), can someone help me correct it?

/* Loops through spreadsheet rows. If there is no Document Link, a new document will be generated. */
function createNewGoogleDocs() {

  const googleDocTemplate = DriveApp.getFileById('TEMPLATE_ID_HERE');
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Responses');
  const rows = sheet.getDataRange().getValues();
  
  rows.forEach(function(row, index) {
    if (index === 0) return;
    if (row[13]) return;

    const parent_folder = DriveApp.getFoldersByName(row[3]).next();
    const subfolder = parent_folder.getFoldersByName(row[2]).next();
    const destinationFolder = DriveApp.getFoldersByName(subfolder).next();
    const copy = googleDocTemplate.makeCopy(`QCP - ${row[3]} - ${row[2]}`, destinationFolder);
    const doc = DocumentApp.openById(copy.getId());
    const body = doc.getBody();

    body.replaceText('{{Month}}', row[2]);
    body.replaceText('{{Name}}', row[3]);
    body.replaceText('{{Improvement 1}}', row[11]);
    body.replaceText('{{Improvement 2}}', row[12]);

    doc.saveAndClose();
    const url = doc.getUrl();
    sheet.getRange(index   1, 14).setValue(url);
  });
}

I was able to find the answer thanks to Yuri. The problem was that the subfolder had a space the data did not. To correct this problem, Yuri showed me how to make my code create the folder if it doesn't exist. Please see below for fixed code.

/* Loops through spreadsheet rows. If there is no Document Link, a new document will be generated. */
function createNewGoogleDocs() {

  const googleDocTemplate = DriveApp.getFileById('TEMPLATE_ID_HERE');
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Responses');
  const rows = sheet.getDataRange().getValues();
  
  rows.forEach(function(row, index) {
    if (index === 0) return;
    if (row[13]) return;

    const parent_folder = DriveApp.getFoldersByName(row[3]).next();
    try { 
      subfolder = parent_folder.getFoldersByName(row[2]).next(); 
      }
    catch(e) { 
      subfolder = parent_folder.createFolder(row[2]);
      }
    const copy = googleDocTemplate.makeCopy(`QCP - ${row[3]} - ${row[2]}`, subfolder);
    const doc = DocumentApp.openById(copy.getId());
    const body = doc.getBody();

    body.replaceText('{{Month}}', row[2]);
    body.replaceText('{{Name}}', row[3]);
    body.replaceText('{{Improvement 1}}', row[11]);
    body.replaceText('{{Improvement 2}}', row[12]);

    doc.saveAndClose();
    const url = doc.getUrl();
    sheet.getRange(index   1, 14).setValue(url);
  });
}

CodePudding user response:

As a guess. Try to change these lines:

const subfolder = parent_folder.getFoldersByName(row[2]).next();
const destinationFolder = DriveApp.getFoldersByName(subfolder).next();
const copy = googleDocTemplate.makeCopy(`QCP - ${row[3]} - ${row[2]}`, destinationFolder);

With:

try { const subfolder = parent_folder.getFoldersByName(row[2]).next() }
catch(e) { const subfolder = parent_folder.createFolder(row[2]) }
const copy = googleDocTemplate.makeCopy(`QCP - ${row[3]} - ${row[2]}`, subfolder);

It tries to get the subfolder. In case the subfolder doesn't exists it creates the subfolder.

  • Related