Google-api-nodejs-client: Is there a way to use await and async instead callbacks?

Created on 8 Nov 2017  路  5Comments  路  Source: googleapis/google-api-nodejs-client

Currently, the code example is.:

var google = require('googleapis');
var cloudResourceManager = google.cloudresourcemanager('v1');

authorize(function(authClient) {
  var request = {
    auth: authClient,
  };

  var handlePage = function(err, response) {
    if (err) {
      console.error(err);
      return;
    }

    var projectsPage = response['projects'];
    if (!projectsPage) {
      return;
    }
    for (var i = 0; i < projectsPage.length; i++) {
      // TODO: Change code below to process each resource in `projectsPage`:
      console.log(JSON.stringify(projectsPage[i], null, 2));
    }

    if (response.nextPageToken) {
      request.pageToken = response.nextPageToken;
      cloudResourceManager.projects.list(request, handlePage);
    }
  };

  cloudResourceManager.projects.list(request, handlePage);
});

function authorize(callback) {
  google.auth.getApplicationDefault(function(err, authClient) {
    if (err) {
      console.error('authentication failed: ', err);
      return;
    }
    if (authClient.createScopedRequired && authClient.createScopedRequired()) {
      var scopes = ['https://www.googleapis.com/auth/cloud-platform'];
      authClient = authClient.createScoped(scopes);
    }
    callback(authClient);
  });
}

Is there a way to use this example using async/await features? My problem is handle async errors.

Thanks!

Most helpful comment

I had a similar issue and found out that it happens due to util.promisify() not passing the context.

An alternative solution I found was to use Bluebird's Promisify which allows context as an option. So you would use something like:

const { promisify } = require('bluebird');
...
const authAsync = promisify(google.auth.getApplicationDefault, { context: google.auth });

Which would then bind google.auth to this and provide access to that property.

All 5 comments

If you are using node >= v8, you can use util.promisify() on callback functions and then use async / await on them.

EDIT:
@BrunoQuaresma, to pass the context, you can use apply. Try something like:

const authAsync = promisify(google.auth.getApplicationDefault);
const authClient = await authAsync.apply(google.auth);

I try this.:

const authAsync = promisify(google.auth.getApplicationDefault);
....
const authClient = await authAsync();

but throws this error: "Cannot read property '_cachedCredential' of undefined"

I had a similar issue and found out that it happens due to util.promisify() not passing the context.

An alternative solution I found was to use Bluebird's Promisify which allows context as an option. So you would use something like:

const { promisify } = require('bluebird');
...
const authAsync = promisify(google.auth.getApplicationDefault, { context: google.auth });

Which would then bind google.auth to this and provide access to that property.

For someone is looking for async'd Google API functions, try googleapis-async.
It's currently not supporting for async'd google.auth, though.

Closing in favor of #523

Was this page helpful?
0 / 5 - 0 ratings

Related issues

eduDorus picture eduDorus  路  3Comments

ovaris picture ovaris  路  3Comments

raapperez picture raapperez  路  3Comments

hainguyents13 picture hainguyents13  路  3Comments

streamnsight picture streamnsight  路  4Comments