Nodejs 和 Google 电子表格集成(无法读取未定义的属性"长度")



我已经开始使用nodejs(并且对javascript有初级的理解(。

目前遵循谷歌电子表格API指南建立一个小型应用程序。https://developers.google.com/sheets/api/quickstart/nodejs

虽然我能够与我的谷歌表单建立连接,并能够获取数据,但我希望通过以下特定方式实现它。

将数据获取代码放在一个文件中(fetchdatafromgoglesheet.jsgetdata((函数获取数据并将其作为行返回到主函数(稍后使用我的主文件(start.js(中的数据,然后根据这些值执行操作。

然而,我无法实现这两个文件的代码共享。请帮忙。

start.js

const googlesheet = require('./fetchdatafromgooglesheet');
var rows=googlesheet.getData();
console.log(rows.length);

从谷歌标签获取数据

const fs = require('fs');
const readline = require('readline');
const {google} = require('googleapis');
//var rows=null;
// If modifying these scopes, delete token.json.
const SCOPES = ['https://www.googleapis.com/auth/spreadsheets.readonly'];
// The file token.json stores the user's access and refresh tokens, and is
// created automatically when the authorization flow completes for the first
// time.
const TOKEN_PATH = 'token.json';
var rows;
const getData= ()=>
{

// Load client secrets from a local file.
fs.readFile('credentials.json', (err, content) => {
if (err) return console.log('Error loading client secret file:', err);
// Authorize a client with credentials, then call the Google Sheets API.
authorize(JSON.parse(content), listMajors);
});
return rows;
}
/**
* Create an OAuth2 client with the given credentials, and then execute the
* given callback function.
* @param {Object} credentials The authorization client credentials.
* @param {function} callback The callback to call with the authorized client.
*/
function authorize(credentials, callback) {
const {client_secret, client_id, redirect_uris} = credentials.installed;
const oAuth2Client = new google.auth.OAuth2(
client_id, client_secret, redirect_uris[0]);
// Check if we have previously stored a token.
fs.readFile(TOKEN_PATH, (err, token) => {
if (err) return getNewToken(oAuth2Client, callback);
oAuth2Client.setCredentials(JSON.parse(token));
callback(oAuth2Client);
});
}
/**
* Get and store new token after prompting for user authorization, and then
* execute the given callback with the authorized OAuth2 client.
* @param {google.auth.OAuth2} oAuth2Client The OAuth2 client to get token for.
* @param {getEventsCallback} callback The callback for the authorized client.
*/
function getNewToken(oAuth2Client, callback) {
const authUrl = oAuth2Client.generateAuthUrl({
access_type: 'offline',
scope: SCOPES,
});
console.log('Authorize this app by visiting this url:', authUrl);
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
rl.question('Enter the code from that page here: ', (code) => {
rl.close();
oAuth2Client.getToken(code, (err, token) => {
if (err) return console.error('Error while trying to retrieve access token', err);
oAuth2Client.setCredentials(token);
// Store the token to disk for later program executions
fs.writeFile(TOKEN_PATH, JSON.stringify(token), (err) => {
if (err) return console.error(err);
console.log('Token stored to', TOKEN_PATH);
});
callback(oAuth2Client);
});
});
}
/**
* Prints the names and majors of students in a sample spreadsheet:
* @see https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms/edit
* @param {google.auth.OAuth2} auth The authenticated Google OAuth client.
*/
function listMajors(auth) {
const sheets = google.sheets({version: 'v4', auth});
sheets.spreadsheets.values.get({
spreadsheetId: '1MMx_OcwmQApgKJUVdU0ySC_lUx1FB6-81AfV3E',
range: 'Sheet2!A2:F',
}, (err, res) => {
if (err) return console.log('The API returned an error: ' + err);
var fetchedData = res.data.values;
rows=fetchedData;
});
}
module.exports={getData};

执行时出现以下错误。

D:studynodejsgooglesheetstart.js:5
console.log(rows.length);
^
TypeError: Cannot read property 'length' of undefined
at Object.<anonymous> (D:studynodejsgooglesheetstart.js:5:18)
at Module._compile (internal/modules/cjs/loader.js:1138:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1158:10)
at Module.load (internal/modules/cjs/loader.js:986:32)
at Function.Module._load (internal/modules/cjs/loader.js:879:14)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
at internal/main/run_main_module.js:17:47

经过一些研究和跟进其他人的建议,我修改了下面的代码,它完成了任务,但我认为这不是正确的做事方式。请告诉我(这是修改后的代码(

function fetchData () {

var rows=googlesheet.getData();
if (rows==undefined && rows==null) {
setTimeout(fetchData, 300); 
} else {
//setTimeout(fetchData, 300); // try again in 300 milliseconds
console.log(rows.length);
}
}

fetchData();

由于rowsundefined,因此无法访问length属性。最好做一个undefined&null检查之前。

const googlesheet = require('./fetchdatafromgooglesheet');
rows=googlesheet.getData();
if(rows!==undefined && rows!==null) console.log(rows.length);

更新:

  1. 由于getData()async方法,您必须等待它使用await关键字获取结果。

    rows = await googlesheet.getData();
    
  2. 但是,由于只能在异步函数中使用await,因此必须使用Promise.then()方法,因为async方法总是返回Promise

    const googlesheet = require('./fetchdatafromgooglesheet');
    googlesheet.getData()
    .then((rows) => { console.log(rows.length) });
    

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function

最新更新