kickehy
kickehy

Reputation: 21

Error when <input type="file"> is blank on a submitted form (Google App Script)

I'm creating a Google Web App (which is a HTML form) that will upload a file to a folder on My Drive. It's not required to have a file to upload, so there will be times where this input will essentially be "blank". The app works perfectly fine, except when you don't choose a file to upload. It spits out this error: "Exception: We're sorry, a server error occurred. Please wait a bit and try again." I have two files, the html file and the .gs file. Here's they are:

/* The script is deployed as a web app and renders the form */
function doGet(e) {
  return HtmlService.createHtmlOutputFromFile('FormFrontend.html');
}

/* This function will process the submitted form */
function uploadFiles(form) {
  try {
    /* Name of the Drive folder where the files should be saved */
    var dropfolder = "Uploaded Files";
    var folder, folders = DriveApp.getFoldersByName(dropfolder);

    /* Find the folder, create the folder if it does not exist */
    if (folders.hasNext()) {
      folder = folders.next();
    } else {
      folder = DriveApp.createFolder(dropfolder);
    }

    /* Get the file uploaded though the form as a blob */
    var blob = form.myFile;
    var file = folder.createFile(blob);
    var urlstr = file.getUrl()

    /* Set the file description as the name of the uploader */
    file.setDescription("Uploaded by " + form.ContactName);

    /* Write response to spreadsheet */
    var ss = SpreadsheetApp.openById("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
    var responses = ss.getSheetByName("Responses");
    responses.appendRow([form.CompanyName, form.ContactName, form.PhoneNumber, form.Email, form.Date, form.Severity, form.Details, urlstr])

    /* As long as there's no errors you should se the below text */
    return "Form Submitted Successfully "

  } catch (error) {

    /* If there's an error, show the error message */
    return error.toString();
  }

}
<html>

<body>
  <!-- This is the actual HTML form -->
  <div id="theform">
    <form id="myForm">

      <p style="font-size:30px">Customer Form</p>

      Company Name:
      <input type="text" name="CompanyName">
      <br>Contact Name:
      <input type="text" name="ContactName">
      <br>Phone Number:
      <input type="text" name="PhoneNumber">
      <br>Contact Email:
      <input type="email" name="Email">
      <br>Date:
      <input type="date" name="Date">
      <br>Overall Severity: (1 Lowest, 5 Highest)
      <br>
      <input type="number" name="Severity" min="1" max="5" value="1">
      <br>Details:

      <br>
      <textarea name="Details" rows=10 cols=65></textarea>
      <br>
      <br>Additional File (Optional):
      <input type="file" name="myFile">
      <br>

      <!-- The submit button. It calls the server side function uploadFiles() on click -->
      <input type="submit" value="Submit" onclick="this.value='Submitting..';
                    google.script.run.withSuccessHandler(fileUploaded)
                    .uploadFiles(this.parentNode);
                    return false;">
    </form>
  </div>

  <!-- Here the results of the form submission will be displayed -->
  <div id="output"></div>
</body>

</html>

<!-- The function will be called after the Google Script has executed -->
<script>
  function fileUploaded(status) {
    document.getElementById('myForm').style.display = 'none';
    document.getElementById('output').innerHTML = status;
  }
</script>

If have tried putting an IF statement around the "/* Get the file uploaded though the form as a blob */" section that tells it to just set urlstr to nothing if form.myFile is blank, but it still fails (but if you choose an actual file, it still completes successfully). I haven't been able to get anything helpful to show up in the logger either.

I'm fairly new to Google App Script, so any help would be appreciated!

Upvotes: 1

Views: 1654

Answers (2)

kickehy
kickehy

Reputation: 21

This is what ended up working. The .getContentType seems to always return "application/octet-stream" when it's left blank and checking to see if the returned content type is that specific one worked.

/* Get the file uploaded though the form as a blob */
var blob = form.myFile;
var contentType = blob.getContentType();

if (contentType != "application/octet-stream") {
    var file = folder.createFile(blob);
    var urlstr = file.getUrl();
    /* Set the file description as the name of the uploader */
    file.setDescription("Uploaded by " + form.ContactName);
 } else {
    var urlStr = "None given";
 }

Upvotes: 1

Alan Wells
Alan Wells

Reputation: 31300

I'd check what is actually getting returned into the variable blob.

var blob = form.myFile;

Maybe check the type with JavaScript typeOf.

var whatsTheType = typeOf blob;

In this test function:

function testIt() { 
  var newTestFile = DriveApp.createFile('New Text File', 'Hello, world!');
  var myBlob = newTestFile.getBlob();

  var whatsTheType = typeof myBlob;
  Logger.log('whatsTheType: ' + whatsTheType);
}

JavaScript typeof returns the type of the blob as an "object". If you check the typeof, and it's not an object, then the file wasn't uploaded.

Put in an if conditional check, rather than a "try/catch". The "try/catch" obviously isn't keeping the code from dying.

if (whatsTheType === "object") {
  //Create the file
  var file = folder.createFile(blob);
};

Alternatively, you should be able to check the value property of the file picker to return a name, if a file was uploaded. If there is no name for the uploaded file, then the user didn't use the file picker.

Upvotes: 0

Related Questions