Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Promisifying Sheet API v4 causes undefined this

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();
like image 736
Christopher Krah Avatar asked Aug 17 '18 00:08

Christopher Krah


People also ask

How does promisify work in JavaScript?

That wrapper returns a promise and forwards the call to the original f, tracking the result in the custom callback (**). Here, promisify assumes that the original function expects a callback with exactly two arguments (err, result). That’s what we encounter most often.

What is the sheets API?

The Sheets API gives you full control over the content and appearence of your spreadsheet data.

How does promisify return a promise?

A call to promisify (f) returns a wrapper around f (*). That wrapper returns a promise and forwards the call to the original f, tracking the result in the custom callback (**). Here, promisify assumes that the original function expects a callback with exactly two arguments (err, result). That’s what we encounter most often.

Can promisification replace callbacks in Node JS?

In Node.js, there’s a built-in util.promisify function for that. Promisification is a great approach, especially when you use async/await (see the next chapter), but not a total replacement for callbacks.


1 Answers

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.

like image 73
Christopher Krah Avatar answered Sep 30 '22 05:09

Christopher Krah