Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Folder.searchFiles() method raises "Invalid argument: q" error

Given the following Google Apps Script code snippet:

function myFunction() {
  var files = DriveApp.getFolderById('xxx').searchFiles('123')
  while (files.hasNext()) {
    var file = files.next()
      Logger.log(file.getName())
  }
}

I'm getting:

Invalid argument: q (line x, file "Code")

from the line with while (files.hasNext()) statement.

The line doesn't contain any error I'm aware of. The funny thing is when I exchange .searchFiles('123') with .getFiles(), the error doesn't appear and the code executes.

Does it mean that there's a problem with the object that .searchFiles('123') returns (it should return FileIterator object)? Unfortunately, Javascript only checks the return data type at runtime so I cannot really see if it's correct until I run it.

like image 204
Michal Sz. Avatar asked Jun 09 '26 23:06

Michal Sz.


1 Answers

Per the function documentation of searchFiles, the expected argument is a query string that conforms to the syntax described in the Google Drive API's "Search for Files " guide

Gets a collection of all files in the user's Drive that match the given search criteria. The search criteria are detailed in the Google Drive SDK documentation. Note that the params argument is a query string that may contain string values, so take care to escape quotation marks correctly (for example "title contains 'Gulliver\\'s Travels'" or 'title contains "Gulliver\'s Travels"').

Note that Drive v2 uses title for the filename, and Drive v3 uses name for the filename. Apps Script's advanced service client library Drive uses v2, so this may be the syntax used by the Drive Service (DriveApp) as well.

The reason the error message does not appear on the line with searchFiles is because the return value is a FileIterator, rather than the actual results. This (and most) iterators are lazily-evaluated, and thus your search query is not actually executed until you call files.hasNext().

To resolve this issue, you must indicate what should be searched and how, i.e. provide the Field and the Operator, not just the Value.

function foo() {
  const queries = ["fullText contains '123'",
                   "mimeType='" + MimeType.GOOGLE_SHEETS + "'"];
  const matches = queries.map(function (qs) {
    return getMatchingFiles_(qs);
  });
  // Log the results in the Apps Script logger. (Use console.log for Stackdriver)
  matches.forEach(function (queryResult, i) {
    Logger.log("Results for query #" + i
               + ", \"" + queries[i] + "\" are:");
    queryResult.forEach(function (file) {
      Logger.log(file.getId() + ": '" + file.getName() + "'");
    });
  });
}

function getMatchingFiles_(query, folderId) {
  // Default to DriveApp.searchFiles if no folder ID given.
  folder = folderId ? DriveApp.getFolderById(folderId) : DriveApp;
  const search = folder.searchFiles(query);
  const results = [];
  while (search.hasNext())
    results.push(search.next());

  return results;
}
like image 119
tehhowch Avatar answered Jun 11 '26 21:06

tehhowch



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!