开发者问题收集

在 Google Apps Script 中,已知类型的变量从服务器端(.gs)传递到客户端(html)时变为“未定义”

2019-07-02
1155

在 google apps 脚本中,我有一个 html 文件,其中有一个 onsuccess 回调函数,该函数调用服务器端函数,该函数从相关电子表格中获取一些数据,然后将存储在变量中的数据返回给 html 脚本函数 onsuccess。

我之前已经成功做到了。这就是为什么我如此困惑,为什么出于某种原因,我从服务器端返回的变量一旦返回到客户端函数就会变为“未定义”。

我认为它是某种类型错误,所以我尝试将变量(一个最多包含三个元素的非常小的数组)和/或数组元素转换为已知类型(string,int),然后将它们推送到新变量中并创建一个包含新已知类型元素的新数组。还使用“typeof”检查了原始数组元素,它们都是字符串,正如预期的那样,所以我变得更加困惑,因为它看起来不像是 TypeError。

html 回调函数:(编辑以显示要点)

google.script.run.withSuccessHandler(

          function (flavors) 
           {            
            console.log(flavors);  // undefined
           }
        ).getBatchFlavs();

code.gs:(编辑以显示要点)

function getBatchFlavs() {

  var ss = SpreadsheetApp.getActive();
  var sheet = ss.getSheetByName("Flavoring");
  var data = sheet.getDataRange().getValues();
  var flavCell = sheet.getRange(1,3);

  data.forEach(function(row,i) {

    var rule = flavCell.getDataValidation();

      if (rule != null) 
        {
          var flavs = rule.getCriteriaValues(); 
          var flavors = flavs[0]; 

          Logger.log(flavors);  // shows exactly what i'm expecting
          Logger.log(typeof flavors);                 

          return flavors;  
        }
  })
}

console.log 打印“undefined”。

我包含了 .gs 代码的一部分,其中我从具有数据验证选项的单元格中获取要传递给客户端的变量的数据,这些选项是字符串。我想也许这可能会创建一些奇怪的变量类型或未知的东西,但正如我所说,我已经用“typeof”检查了类型,并且 flavors 数组中的项目确实是字符串。

2个回答

问题:

  • 服务器端函数 getBatchFlavs() 没有返回值。 return flavors; 仅将值返回给传递给 Array#forEach 的匿名回调函数。

解决方案:

  • returngoogle.script.run - getBatchFlavs() 调用的函数中返回某些内容

代码片段:

function getBatchFlavs() {//<================
  data.forEach(function(row, i) {//<==      |
    if (rule != null) {//            |      |
      var flavors = flavs[0];//      |      |
      Logger.log(flavors); //        |      |
      return flavors;//==============       |
    }//                                     |
  });//                                     |
  return flavors;//=========================
}
TheMaster
2019-07-02

对于可以传递的内容有一些限制。请阅读此 参数和返回值

我做了这个例子,它有效:

function showmydialog() {
  var html='<html><head><script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script><link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css"><script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script></head><body>';
  html+='<div id="tst"></div>';
  html+='<script>$(function(){google.script.run.withSuccessHandler(function(vA){$("#tst").html(vA.join());}).getMyFlavors();});</script>';
  var ui=HtmlService.createHtmlOutput(html);
  SpreadsheetApp.getUi().showModelessDialog(ui, "Flavors");
}

function getMyFlavors() {
  var ss=SpreadsheetApp.getActive();
  var sh=ss.getSheetByName('Sheet2');
  var rg=sh.getRange('A1');//this has the data validation from the flavors named range
  var rule = rg.getDataValidation();
  if (rule != null) 
  {
    var flavs = rule.getCriteriaValues();      
    //return flavs[0].getValues();  
    return rule.getCriteriaValues()[0].getValues().map(function(r){return r[0];}); //This should flatten out the array.
  }
}

我创建了一个名为 flavors 的命名范围。

这是我的电子表格的样子:

enter image description here

这是我的对话框的样子:

enter image description here

数据通过 dom ready 函数加载到页面上。

Cooper
2019-07-02