Promisifying Sheet API v4 causes undefined this

Christopher Krah Source

If I use callbacks, the code below using Google's Sheets API v4 works fine.

However, I am trying to apply util.promisify to the API call. This causes:

Cannot read property 'getRoot' of undefined

which is thrown from :

node_modules\googleapis\build\src\apis\sheets\v4.js:592

This line 592 says: context: this.getRoot()

I am probably not using promisify correctly and I hope that someone here can help me.

I suspect it might have something to do with concurrency.

Any tip would be appreciated.

let {
  promisify
} = require('util');
let {
  google
} = require('googleapis');
let sheets = google.sheets('v4');
let credentials = require('./credentials.json')

let client = new google.auth.JWT(
  credentials.client_email, null, credentials.private_key, ['https://www.googleapis.com/auth/spreadsheets'])
client.authorize((err, tokens) => {
  if (err) {
    throw err;
  }
});

let endpoint = promisify(sheets.spreadsheets.values.get);

async function test() {

  let request = {
    auth: client,
    spreadsheetId: "xxxxxxxx",
    range: "'ExampleSheet'!A:B",
    valueRenderOption: "UNFORMATTED_VALUE",
    majorDimension: "ROWS",
  }

  let result = await endpoint(request)
    .then((res) => {
      return res
    })
    .catch((err) => {
      console.log(err);
    });
}

test();
javascriptnode.jsnpmconcurrencygoogle-spreadsheet

Answers

answered 1 month ago Jacob #1

Try returning the result. Edit: If I am remembering correctly async will create promises inside the function. Try the endpoint without promisify inside the async function. Edit: Maybe try this, it is possible the credntials were causing some async issue.

I am also fairly certain you don't need the .then() on await .then() is a promise syntax and async/await are slightly different, I mean you can do stuff like that... Let's just see if this works.

 async function test() {
      let client = await new google.auth.JWT(
      credentials.client_email, null, credentials.private_key, ['https://www.googleapis.com/auth/spreadsheets'])
    client.authorize((err, tokens) => {
      if (err) {
        throw err;
      }
    });

      let request = {
        auth: client,
        spreadsheetId: "xxxxxxxx",
        range: "'ExampleSheet'!A:B",
        valueRenderOption: "UNFORMATTED_VALUE",
        majorDimension: "ROWS",
      }
     let endpoint = await sheets.spreadsheets.values.get
     let result = await endpoint(request)
     return result  
    }

    test();

answered 1 month ago Christopher Krah #2

Okay, after some more digging I got it to work.

I modified my original code to use the following:

let endpoint = promisify(api.spreadsheets.get.bind(api));

Not sure why api isn't bound to this/the context in the first place though.

comments powered by Disqus