通过 API 将 JSON 拉入 Google 表格,导致单元格中出现未定义的值

Pulling JSON into Google Sheet via API resulting in undefined values in cells

本文关键字:单元格 未定义 JSON API 拉入 Google 表格 通过      更新时间:2023-09-26

>我的一个API有问题,我正在尝试建立一个API来调用一个名为Streak的客户关系管理工具,我正在尝试通过HTTP Basic Auth GET提取数据,该GET通过我的脚本逻辑解析JSON文件,然后解析到我的Google Sheets电子表格中。经过几个小时的开发,Google App 脚本完美无缺地工作(满足我的要求),我的脚本在找不到值时将字符串"undefined"插入我的 google 工作表单元格中,一个完全空的不存在的字段。

谷歌表格输出问题的图像可以在下面看到注意:我突出显示了导致我悲伤的字段属性名称和未定义的值https://drive.google.com/file/d/0B4rXaBEqs2UzSU5fMFUxYW8zTm8/view?usp=sharing

下面

可以看到将数百条记录推断到我的Google表格的整个代码片段。据我了解,我的问题在语句row.push(字段1001 -> 1021)中,它总是试图将所有字段推送到工作表中;但是,并非所有记录都包含这些字段,因为我可能没有在源CRM中填充它们。为此,脚本在我的工作表中的相应单元格中填充"未定义"字符串。

我希望防止在工作表中填充这个"未定义"的字符串,而不是这个单元格应该是空白的,有人可以告诉我如何调整我的代码片段来实现这一点吗?非常感谢!我已经尝试了近 2-3 个小时来解决这个问题,但我没有足够的经验来找到答案,我尝试了各种 IF 语句并研究了定义变量类型(即整数、浮点数、字符等)似乎都不起作用。我相信一旦您知道解决方案,解决方案就很简单,非常感谢您的帮助!

//Within this API we need to achieve collecting my data from Streak CRM us
//
//  Notes on Google API 
//      https://developers.google.com/apps-script/guides/services/external
//
//  Notes on Streak API
//    https://www.streak.com/api/
//
//API Key YOUR_API_KEY Here
function myStreak() {
//Google Sheet Data
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheets = ss.getSheets();
  var sheet = ss.getSheetByName("StreakCRM"); 

//Streak API Call  
 var consumerKey = 'YOUR_API_KEY_HERE'
 var url = "https://www.streak.com/api/v1/boxes";  
 var headers = {
             "contentType": "application/json",
             "headers":{
"User-Agent": "MY_APP_NAME (App URL/your email address)",
               "Authorization": "Basic " + Utilities.base64Encode(consumerKey)
             },
             "validateHttpsCertificates" :false
             };
//Fetch Streak Data  
 var response = UrlFetchApp.fetch(url, headers);
 var dataAll = JSON.parse(response.getContentText());
//Write Captured Streak Data to Google Sheet  
 var dataSet = dataAll;  
 var rows = [],
  data; 
  for (i = 0; i < dataSet.length; i++) {
  data = dataSet[i];
  rows.push([data.name,
               data.stageKey,
//             data.fields['1001'], empty field
               data.fields['1002'],
               data.fields['1003'],
//             data.fields['1004'], empty field
               data.fields['1005'],
               data.fields['1006'],
               data.fields['1007'],
               data.fields['1008'],
               data.fields['1009'],
               data.fields['1010'],
               data.fields['1011'],
               data.fields['1012'],
//             data.fields['1013'], empty field
               data.fields['1014'],
               data.fields['1015'],
//             data.fields['1016'], empty field
               data.fields['1017'],
               data.fields['1018'],
               data.fields['1019'],
//             data.fields['1020'], empty field
               data.fields['1021'],
               data.fields['1023']]);//your JSON entities here
}
  dataRange = sheet.getRange(3, 1, rows.length, 19); // 19 Denotes total number of entites
  dataRange.setValues(rows);
//Capture response code success or errors
var text = response.getResponseCode();
Logger.log(text);
Logger.log(response);
}

你已经接受了一个很好的答案,但如果我可以提供另一种修改方法。

//Write Captured Streak Data to Google Sheet  
  var dataSet = dataAll,
      rows = [],
      data,
      dataFields = ['name', 'stageKey', '1001' … ]; //include all the JSON fields you want to transfer including any deliberate blanks you don't exist. 
for (i = 0; i < dataSet.length; i++) {
  data = dataSet[i];
  rows.push(dataFields.map(function (f) {
    return data[f] || '';
  });
}

这里的重点是在一开始就控制一次数据字段的直接映射。

在循环结束时,如果投入到很好的措施中,您将看到三元的另一种替代方案。

return data[f] || '';

这是在形式上

var foo = bar || 'default';

||是你从 if 语句中知道的 OR。实际上,这种模式说"让foo bar,除非它是falsey在这种情况下使用'默认'。

这是预期的行为,因为这些属性在给定的数据行中完全缺失,因此它们是未定义的变量。当您将未定义的变量写入工作表时,它会转换为字符串"undefined"。

若要处理此问题,应检查每个属性名称以确保其存在,以及它是否不使用所需的默认值。

提到你尝试了各种 If 语句。检查值是否特别未定义的方法是:

if(data.fields['somefieldname'] === undefined)

但是,通常您只想知道该值的计算结果是否为 false,在这种情况下,您只需执行以下操作:

if(data.fields['somefieldname'])

如果 data.fields['somefieldname'] 是计算结果为 false 的任何值,例如 nullfalse0未定义,则计算结果为 False,对于任何其他值为 true。

最后,由于 if 语句对于这种特殊用法来说有点长,我建议使用"条件运算符"或"三元运算符"在您的代码中处理这个问题:

   ( (data.fields['1002'])? data.fields['1002'] : '' )

可以读作"如果 data.fields['1002'] 为 true,则返回 data.fields['1002'],否则返回空字符串"

下面是有关条件运算符的一些文档:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator

在代码的截图中,它看起来像这样:

rows.push([data.name,
               data.stageKey,
//             data.fields['1001'], empty field
               (data.fields['1002'])?data.fields['1002']:'',
               (data.fields['1003'])?data.fields['1002']:'',
               ...
               ...
            ]);

您可以为"else"条件指定任何值,例如,0 而不是空字符串。