0

I am trying to convert an ES2018 async function into an ES2015 (ES6) function, but I get a timeout, guess my ES2015 version is wrong...but where?

ES2018 version

    async function connectGoogleAPI () {
      // Create a new JWT client using the key file downloaded from the Google Developer Console
      const client = await google.auth.getClient({
        keyFile: path.join(__dirname, 'service-key.json'),
        scopes: 'https://www.googleapis.com/auth/drive.readonly'
      });

      // Obtain a new drive client, making sure you pass along the auth client
      const drive = google.drive({
        version: 'v2',
        auth: client
      });

      // Make an authorized request to list Drive files.
      const res = await drive.files.list();
      console.log(res.data);

      return res.data;
    }

ES2015 version w/Promise

    function connectGoogleAPI () {
      return new Promise((resolve, reject) => {
        const authClient = google.auth.getClient({
          keyFile: path.join(__dirname, 'service-key.json'),
          scopes: 'https://www.googleapis.com/auth/drive.readonly'
        });
        google.drive({
          version: 'v2',
          auth: authClient
        }), (err, response) => {
          if(err) {
            reject(err);
          } else {
            resolve(response);
          }
        }
      });
    }
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875

1 Answers1

4

You haven't translated the await of getClient. Remember, await = then (roughly). You're also falling prey to the promise creation anti-pattern: When you already have a promise (from getClient), you almost never need to use new Promise. Just use then.

Here's an example with each await converted into a then, using the chain for the subsequent operations:

function connectGoogleAPI () {
  // Create a new JWT client using the key file downloaded from the Google Developer Console
  return google.auth.getClient({
    keyFile: path.join(__dirname, 'service-key.json'),
    scopes: 'https://www.googleapis.com/auth/drive.readonly'
  }).then(client => {
      // Obtain a new drive client, making sure you pass along the auth client
      const drive = google.drive({
        version: 'v2',
        auth: client
      });

      // Make an authorized request to list Drive files.
      return drive.files.list();
  }).then(res => {
      console.log(res.data);
      return res.data;
  });
}

That last part can be just

  }).then(res => res.data);

...if you remove the console.log. (Or we could abuse the comma operator.)

Notes:

  • Each await needs to become a then handler (there were two in the original, awaiting getClient and drive.files.list)
  • In a then handler, if you have to wait for another promise (such as the one from drive.files.list) you typically return it from the handler, and then use another handler to handle that result (which is why I have return drive.files.list() and then a separate handler for converting res to res.data)

Re that second point: Sometimes nesting is appropriate, such as when you need to combine the result with some intermediate value you only have with in your then handler. (For instance, if we wanted to combine res.data with client.) But generally, prefer not to nest.

Gabriele Petrioli
  • 191,379
  • 34
  • 261
  • 317
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • Thanks a lot for your feedback... going to test it now –  May 22 '18 at 16:24
  • Up and running ! So cool... this function is executed inside a Firebase function, using the default Firebase project App Engine service account ( w role Account Token Creator) . This service account is authorized to access the Google Drive API within the given scope... Well done –  May 23 '18 at 06:08