1

I'm trying to create a class in Javascript basically to do all the google sheet functions. And before writing any function I'm calling the authenticate API in the constructor, but the authentication is not being completed before calling the actual function. Here's the code in the class file,

const { google } = require("googleapis")
const authentication = require("./authentication");

class Sheets {
    constructor() {
        this.test = 'stackoverflow';
        authentication.authenticate().then((auth)=>{
            this.auth = auth;
        });
    }

    async writeToSheet(spreadsheetId, range, data) {
        if(typeof spreadsheetId != "undefined") {
            console.log(this.test)
            console.log('Got the spreadsheetId:' + spreadsheetId)
            console.log('Got the auth:' + this.auth)
            return;    
        }

        var sheets = google.sheets('v4');
        await sheets.spreadsheets.values.update({
            auth: this.auth,
            spreadsheetId: spreadsheetId,
            range: range, //Change Sheet1 if your worksheet's name is something else
            valueInputOption: "USER_ENTERED",
            resource: {
                values: data
            }
        }, (err, response) => {
            if (err) {
            console.log('The API returned an error: ' + err);
            return;
            } else {
                console.log("Data updated to the sheet successfully!");
            }
        });
    } 
}

module.exports = Sheets;

And this is how I'm calling the function,

let sheets = await new Sheets();
sheets.writeToSheet(spreadSheetId, range, data);

When I'm calling the writeToSheet function as above, It's always printing the auth as undefined only like this,

stackoverflow
Got the spreadsheetId:9ijWvEeWG7Oybv_TJi5AMkjl18dFHMFcBfSfkEG24-p7
Got the auth:undefined

So, how to call the authenticate function before calling any other function in the class and set the this.auth synchronously? Any help on this would be greatly appreciated.

2
  • Your class doesn’t have a constructor. Commented Aug 1, 2019 at 3:16
  • @Ry- I missed to add it here, please check now. Thanks. Commented Aug 1, 2019 at 3:30

1 Answer 1

2

I think you just need to create an extra workflow type function that handles the authentication piece and then passes it to the logic you have for writeToSheet; something like this:

const { google } = require("googleapis")
const authentication = require("./authentication");

class Sheets {
    async authenticate() {
        const auth = await authentication.authenticate();
        this.auth = auth;
    }

    async writeToSheet(spreadsheetId, range, data) {
        await this.authenticate();
        await _writeToSheet(spreadsheetId, range, data);
    } 

    async _writeToSheet(spreadsheetId, range, data){
        if(typeof spreadsheetId != "undefined") {
            console.log('Got the spreadsheetId:' + spreadsheetId)
            console.log('Got the auth:' + this.auth)
            return;    
        }

        var sheets = google.sheets('v4');
        await sheets.spreadsheets.values.update({
            auth: this.auth,
            spreadsheetId: spreadsheetId,
            range: range, //Change Sheet1 if your worksheet's name is something else
            valueInputOption: "USER_ENTERED",
            resource: {
                values: data
            }
        }, (err, response) => {
            if (err) {
            console.log('The API returned an error: ' + err);
            return;
            } else {
                console.log("Data updated to the sheet successfully!");
            }
        });
    }
}

module.exports = Sheets;

This slightly alters your use of the function to the following:

let sheets = new Sheets();
await sheets.writeToSheet(spreadSheetId, range, data);

You could add some of this into a constructor instead, but just be mindful that you are storing a class instance that was previously authenticated. It could present an issue if you store the instance and try to reuse it later with a now expired authentication token.

Sign up to request clarification or add additional context in comments.

3 Comments

Can't we do this by using a constructor as like I've shown in my updated code? Because we can't create this kind of function for every function right?
The issue is only if you are storing the Sheets instance for reuse later. You could be introducing an issue where sheets is accessible at a later time and another attempt is made to call writeToSheet with possibly different variables. If authentication expired before the second call, the next writeToSheet would fail automatically.
No prob! Glad to help.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.