【问题标题】:Nodejs And Google spreadsheet Integration ( Cannot read property 'length' of undefined )Nodejs 和 Google 电子表格集成(无法读取未定义的属性“长度”)
【发布时间】:2020-11-19 08:32:08
【问题描述】:

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

目前正在遵循 google Spreadsheet API 指南来构建一个小型应用程序。 https://developers.google.com/sheets/api/quickstart/nodejs

虽然我能够与我的谷歌表格建立连接并能够获取我想要以如下特定方式实现它的数据。

将数据获取代码放在一个文件中(fetchdatafromgooglesheet.js getdata() 函数获取数据并将其作为行返回给主函数) 然后使用我的主文件( start.js )中的数据,然后根据值执行操作。

但是我无法实现这两个文件的代码共享。请帮忙。

start.js

const googlesheet = require('./fetchdatafromgooglesheet');

var rows=googlesheet.getData();

console.log(rows.length);

从 googlesheet 获取数据

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:\study\nodejs\googlesheet\start.js:5
console.log(rows.length);
                 ^

TypeError: Cannot read property 'length' of undefined
    at Object.<anonymous> (D:\study\nodejs\googlesheet\start.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();

【问题讨论】:

标签: javascript node.js google-api google-sheets-api


【解决方案1】:

由于rowsundefined,因此您无法访问length 属性。最好先检查一下undefinednull

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

【讨论】:

  • 它正在获取数据但不显示 rows.length 可能是因为该函数以异步方式工作并且 console.log 在返回 raws 值之前执行。 (javascript新手,这些是我的假设)
  • 你是绝对正确的@linuxgenie。请查看更新后的答案。
  • 它给了我一个错误 googlesheet.getData().then((rows) => { console.log(rows.length) }); ^ TypeError: Cannot read property 'then' of undefined at Object. (D:\study\nodejs\googlesheet\start.js:4:22)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-01-07
  • 1970-01-01
  • 1970-01-01
  • 2020-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多