javascriptgoogle-apps-scriptgoogle-drive-api

While iterating through a loop, Logger.log repeatedly prints the same value


This Google Apps Script works correctly to save a number of Google docs in a folder as PDFs. However, the variable used to store the different file names--when printed with Logger.log--appears not to change. One of the files in the folder is (seemingly) arbitrarily chosen and printed over and over.

//https://github.com/Davor111/google-docs-to-pdf/blob/master/app.js

function gdocToPDF() {
  
  // Replace this ID
    var documentRootFolder = DriveApp.getFolderById("***redacted***") // replace this with the ID of the folder that contains the documents you want to convert

    Logger.log("Downloading " + documentRootFolder.getName() + "...");
    
    var pdfFolder = DriveApp.getFolderById("***redacted***"); // replace this with the ID of the folder that the PDFs should be put in. 

    var documentRootFiles = documentRootFolder.getFiles()

    while(documentRootFiles.hasNext()) {
        createPDF(documentRootFiles.next().getId(), pdfFolder.getId(), function (fileID, folderID) {
            if (fileID) createPDFfile(fileID, folderID);
        })
    }
}


function createPDF(fileID, folderID, callback) {
    var templateFile = DriveApp.getFileById(fileID);
    var templateName = templateFile.getName();
    
    var existingPDFs = DriveApp.getFolderById(folderID).getFiles();

    //in case no files exist
    if (!existingPDFs.hasNext()) {
        return callback(fileID, folderID);
    }

    for (; existingPDFs.hasNext();) {

        var existingPDFfile = existingPDFs.next();
        var existingPDFfileName = existingPDFfile.getName();
        if (existingPDFfileName == templateName + ".pdf") {
            Logger.log("PDF exists already. No PDF created")
            return callback();
        }
        if (!existingPDFs.hasNext()) {
            Logger.log(existingPDFfileName + " created")
            return callback(fileID, folderID)
        }
    }
}

function createPDFfile(fileID, folderID) {
    var templateFile = DriveApp.getFileById(fileID);
    var folder = DriveApp.getFolderById(folderID);
    var theBlob = templateFile.getBlob().getAs('application/pdf');
    var newPDFFile = folder.createFile(theBlob);
    newPDFFile.setName(templateFile.getName() + '.pdf');

}

What is it about iteration that I am not understanding?

Is there a best practices approach I should be using?


Solution

  • Logger.log() Response

    I tried your code and it's all working the problem I encountered is where the for loop if condition statements response in your logger.log().

    for (; existingPDFs.hasNext();) {
    
        var existingPDFfile = existingPDFs.next();
        var existingPDFfileName = existingPDFfile.getName();
        if (existingPDFfileName == templateName + ".pdf") {
            Logger.log("PDF exists already. No PDF created");
            return callback();
        }
        if (!existingPDFs.hasNext()) {
            Logger.log(existingPDFfileName + " created");
            return callback(fileID, folderID)
        }
    }
    

    I change the response variable in your second if condition in your for loop.

    From this:

    Logger.log(existingPDFfileName + " created");
    

    To this:

    Logger.log(templateName + " created")
    

    Whole Code:

    function gdocToPDF() {
    
      // Replace this ID
      var documentRootFolder = DriveApp.getFolderById("***redacted***") // replace this with the ID of the folder that contains the documents you want to convert
    
      Logger.log("Downloading " + documentRootFolder.getName() + "...");
    
    
      var pdfFolder = DriveApp.getFolderById("***redacted***"); // replace this with the ID of the folder that the PDFs should be put in. 
    
      var documentRootFiles = documentRootFolder.getFiles()
    
      while (documentRootFiles.hasNext()) {
        createPDF(documentRootFiles.next().getId(), pdfFolder.getId(), function (fileID, folderID) {
          if (fileID) createPDFfile(fileID, folderID);
        })
      }
    }
    
    
    function createPDF(fileID, folderID, callback) {
      var templateFile = DriveApp.getFileById(fileID);
      var templateName = templateFile.getName();
      console.log(templateName);
    
    
      var existingPDFs = DriveApp.getFolderById(folderID).getFiles();
    
      //in case no files exist
      if (!existingPDFs.hasNext()) {
        return callback(fileID, folderID);
      } 
    
      for (; existingPDFs.hasNext();) {
        var existingPDFfile = existingPDFs.next();
        var existingPDFfileName = existingPDFfile.getName();
        if (existingPDFfileName == templateName + ".pdf") {
          Logger.log(templateName + " PDF exists already. No PDF created")
          return callback();
        } 
        if (!existingPDFs.hasNext()) {
              Logger.log(templateName + " created")
              return callback(fileID, folderID)
            }
          }
        }
    
    function createPDFfile(fileID, folderID) {
      var templateFile = DriveApp.getFileById(fileID);
      var folder = DriveApp.getFolderById(folderID);
      var theBlob = templateFile.getBlob().getAs('application/pdf');
      var newPDFFile = folder.createFile(theBlob);
      newPDFFile.setName(templateFile.getName() + '.pdf');
    
    }
    

    Sample Output

    Sample Folders based on the script.

    Before Execution

    Drive Photo 1

    Drive Photo 2

    Drive Photo

    After Execution

    Drive Photo 4

    This Output is based on the modified code.

    Drive Photo 5

    Reference: