【问题标题】:Cannot read property 'installed' of undefined express js无法读取未定义 express js 的属性“已安装”
【发布时间】:2020-03-19 09:03:07
【问题描述】:

我无法使用 Express js 或 google sheet api 找到此问题的示例。我正在运行一个接收 POST 请求的快速应用程序,然后将其传递给使用 oAuth2 的函数,然后将数据作为附加行发送到谷歌表

当我调用 updateSheet() 时出现以下错误

UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'installed' of undefined
    at resolve (C:\Users\luther\Desktop\Pantree\index.js:50:69)
    at new Promise (<anonymous>)
    at authorize (C:\Users\luther\Desktop\Pantree\index.js:49:10)
    at updateSheet (C:\Users\luther\Desktop\Pantree\index.js:91:28)
    at app.post (C:\Users\luther\Desktop\Pantree\index.js:161:5)
    at Layer.handle [as handle_request] (C:\Users\luther\Desktop\Pantree\node_modules\express\lib\router\layer.js:95:5)
    at next (C:\Users\luther\Desktop\Pantree\node_modules\express\lib\router\route.js:137:13)
    at Route.dispatch (C:\Users\luther\Desktop\Pantree\node_modules\express\lib\router\route.js:112:3)
    at Layer.handle [as handle_request] (C:\Users\luther\Desktop\Pantree\node_modules\express\lib\router\layer.js:95:5)
    at C:\Users\luther\Desktop\Pantree\node_modules\express\lib\router\index.js:281:22

我不知道为什么在发布时会出现此错误,因为该错误是在我的 authorize() 调用中引发的,该调用在从工作表中获取初始数据时完美运行。

我已更新 google sheet API 范围以允许读取和写入,如下所示。 我在我的资源对象中使用虚拟数据来排除正文解析器的问题,所以目前我从我的帖子请求中所做的只是调用 updateSheet() 没有参数

const SCOPES = ['https://www.googleapis.com/auth/spreadsheets'];
const TOKEN_PATH = 'token.json';


// Load client secrets from a local file.
fs.readFile('client_secret.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), grabSheetData);
});

/**
 * 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) {
  return new Promise(resolve => {  // Added
    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, e => resolve(e)); 
      oAuth2Client.setCredentials(JSON.parse(token));
      resolve(oAuth2Client); 
    });
  });
}


/* GET SHEET DATA */
async function grabSheetData () {
  var data = {
    payload: ''
  }
  const authClient = await authorize(creds);  
  const request = {
    spreadsheetId: 'xxxxxxxxxxxxxxxxxxxx', 
    range: 'A1:C',
    valueRenderOption: "FORMATTED_VALUE",  
    dateTimeRenderOption: "SERIAL_NUMBER",  
    auth: authClient, 
  }

  try {
    const response = (await sheets.spreadsheets.values.get(request)).data;

    console.log(JSON.stringify(response, null, 2));
    data.payload=response
  } catch (err) {
    console.error(err);
  }
  return data
};


/* WRITE TO SHEET */
async function updateSheet () {
  const authClient = await authorize();
  const request = {
    spreadsheetId: 'xxxxxxxxxxxxxxxx', 
    range: 'A7:C7', 
    valueInputOption: 'RAW', 
    insertDataOption: 'INSERT_ROWS',
    resource: {
      item: 'dummyname',
      dateLogged:'dummydate',
      expires:'dummy expire'
    },

    auth: authClient,
  };

  try {
    const response = (await sheets.spreadsheets.values.append(request)).data;

    console.log(JSON.stringify(response, null, 2));
  } catch (err) {
    console.error(err);
  }
}

我的 app.post

app.post('/api/updateSheet', (req,res)=>{
    updateSheet()
});

【问题讨论】:

  • "TypeError: Cannot read property 'installed' of undefined at resolve (C:\Users\luther\Desktop\Pantree\index.js:50:69)" 那么在线index.js 中有什么50? (和 49,基本上它周围的一切=)
  • @mike-pomax-kamermans 我想这是奇怪的部分之一,因为这些行是我的 grabSheetData 函数所在的地方.....但是该函数工作正常,我知道每个函数都需要调用authorize() 使用我的令牌获得授权,但授权功能来自行:34-46
  • 嗯,看起来错误发生在这一行const { client_secret, client_id, redirect_uris } = credentials.installed;,因为credentialsundefinedcredentials 作为参数传递给 authorize(credentials)。因此,在您可以调用授权的地方,您没有传递正确的凭据。您没有在调用 authorize(credentials) 的位置显示代码,因此在这方面我们无能为力。
  • 这并不奇怪。请记住查看错误的含义:UnhandledPromiseRejectionWarning 表示您在某处有一个承诺,但您忘记了.catch(....):在 100% 的情况下,这肯定会导致错误,因此浏览器(和 Node)会警告您当你有一个.then(...) 而没有一个.catch(...) 时。在这种情况下,等待“事物”,但不要访问.data,直到等待解决并绑定到response之后
  • 当您这样做const authClient = await authorize(creds); 时,未处理的拒绝可能发生在grabSheetData()authorize() 失败并且您在此await 周围没有try/catch,因此您会收到未处理的拒绝错误。但是,根本问题是creds 不是它应该的样子。您还应该在 await 周围有一个 try/catch 来捕获错误,但这不是这里的根本问题。

标签: node.js express google-sheets


【解决方案1】:

我忘记在 updateSheets() 调用中将凭据传递给我的授权调用


async function updateSheet () {
  const authClient = await authorize(creds); //PASS CREDS HERE
  const request = {
    spreadsheetId: '1VTiTgPvMvLlOVBhBfoMGrshfMMJJMMzoA6GesheWMPg', 
    range: 'A7:C7', 
    valueInputOption: 'RAW', 
    insertDataOption: 'INSERT_ROWS',
    resource: {
      item: 'dummyname',
      dateLogged:'dummydate',
      expires:'dummy expire'
    },

    auth: authClient,
  };

  try {
    const response = (await sheets.spreadsheets.values.append(request)).data;
    // TODO: Change code below to process the `response` object:
    console.log(JSON.stringify(response, null, 2));
  } catch (err) {
    console.error(err);
  }
}

【讨论】:

  • 而且,您仍然没有从您的某些 await 语句中发现错误。每个await 都可以抛出一个被拒绝的承诺。你需要在调用链中的某个地方捕获它们,如果不是在本地,那么在调用者中。
猜你喜欢
  • 1970-01-01
  • 2018-04-02
  • 2018-12-26
  • 2016-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-04
  • 2016-01-12
相关资源
最近更新 更多