Using sessionStorage in Google Apps Script - Uncaught Type Error: undefined

Using sessionStorage in Google Apps Script - Uncaught Type Error: undefined

我有一个网页(使用 Google Apps 脚本编写)在初始加载时调用服务器,首先获取一组下拉选项以创建过滤器,然后再次调用以初始化时间线图表。我已经拥有这个页面很长时间了,它按预期工作。

我现在正在做的是将一些数据保存到 sessionStorage,这样它就不必每次都调用服务器,以防用户离开页面。这是我第一次尝试这样做,所以我还在学习中。

我的第一步是保存下拉项。一旦我让它工作,我会尝试对图表数据做同样的事情。

我留下了一些原始代码,但注释掉了。

    $(function() {
      //google.script.run.withSuccessHandler(buildDropDowns).buildDropDowns();
      //google.script.run.withSuccessHandler(getChartData).getChartData("-", "-", "-", "-", "-", "-", "-");
      testSession();
    });

    function testSession() {
      if(sessionStorage.getItem("drop") == null) {
        google.script.run.withSuccessHandler(buildDropDowns).buildDropDowns();
      } else {
        buildDropDowns(sessionStorage.getItem("drop"));
      }

      if(sessionStorage.getItem("chart") == null) {
        google.script.run.withSuccessHandler(getChartData).getChartData("-", "-", "-", "-", "-", "-", "-");
      } else {
        getChartData(sessionStorage.getItem("chart"));
      }
    }

    function buildDropDowns(JSONObj) {
      sessionStorage.setItem("drop", JSONObj);
      var dropDownObj = JSON.parse(JSONObj);
      // do a bunch of things with the dropDownObj
    }

    function getChartData(JSONObj) {
      sessionStorage.setItem("chart", JSONObj);
      var dataObj = JSON.parse(JSONObj);
      var rawChartData = dataObj.chartData;
      var count = dataObj.count;
      var colors = dataObj.colors;
      const dateIndices = [3,4];
      const chartData = rawChartData.map(function (row) {
        return row.map(function (col, index) {
          return (dateIndices.indexOf(index) === -1) ? col : new Date(col);
        });
      });
      if(chartData.length == 1) {
        document.getElementById("chartDiv").innerHTML = "<b>No projects meet your criteria</b>";
      } else {
        buildChart(chartData, count, colors);
      }
    }
    
    google.charts.load('current', {'packages':['timeline']});
      
    function buildChart(chartData, count, colors) {
      var container = document.getElementById('chartDiv');

      //*** EDIT - THIS APPEARS TO BE PROBLEM LINE ***
      var chart = new google.visualization.Timeline(container);
      //Is there something about visualizations that are different on a reload?

      var dataTable = new google.visualization.DataTable();
        
      dataTable.addColumn({ type: 'string', id: 'Project' });
      dataTable.addColumn({ type: 'string', id: 'dummy bar label' });
      dataTable.addColumn({ type: 'string', role: 'tooltip', p: {'html':true}});
      dataTable.addColumn({ type: 'date', id: 'Start' });
      dataTable.addColumn({ type: 'date', id: 'End' });
      dataTable.addColumn({ type: 'number', id: 'sortValue' });
      dataTable.addColumn({ type: 'string', id: 'gate' });
        
      dataTable.addRows(chartData);
      
      var options = {
        height: Math.min(800, (chartData.length*45)+60),
        width:"100%",
      };
      
      var view = new google.visualization.DataView(dataTable);
      view.setColumns([0, 1, 2, 3, 4]);  // exclude column 5 (sequence)
      
      chart.draw(view, options);
     
    }

下拉部分确实符合我的预期。第一次打开页面,调用服务器获取数据,将JSONObj保存到sessionStorage中。当刷新页面或导航离开然后再返回时,我可以看到它不是去服务器获取那些下拉项,而是从 sessionStorage 获取 JSONObj,并正确处理它。成功!!

所以我对图表数据进行了同样的尝试。同样,当它第一次加载页面时,它会去服务器获取数据,并将 JSONObj 保存到 sessionStorage。但是当我刷新选项卡(或导航离开和返回)时,它无法正确处理来自 sessionStorage 的 JSONObj。我收到一个 'undefined' 错误,我无法找到它。

使用 console.log(),看起来 JSONObj 最初从服务器发送时与从 sessionData 检索时相同。但很明显,它有一些其他代码不喜欢的地方。它正确处理原件,但在 sessionData 副本上出错。

这只是我遗漏的一些愚蠢的东西吗(同样,这是我第一次尝试使用 sessionData 做事)?或者 sessionData 存储 JSONObj 的方式是否以某种方式改变了它,以便在检索时不能以相同的方式处理它?为什么它适用于 dropDown 进程,而不适用于 chartData 进程?

如有任何正确方向的建议,我们将不胜感激。

感谢@RonM 为我指明了正确的方向。我现在了解到的是,以前,可视化包有时间加载,同时调用服务器来捕获数据。一旦我将服务器从后续加载的流程中移出,数据就会在时间线有机会完成加载之前尝试写入时间线。

我已基于此对代码进行了一些更新,以确保图表包在尝试处理来自 sessionData 的数据之前加载。

    $(function() {
      //google.script.run.withSuccessHandler(buildDropDowns).buildDropDowns();
      //google.script.run.withSuccessHandler(getChartData).getChartData("-", "-", "-", "-", "-", "-", "-");
  
    //testSession();  //COMMENT OUT NOW
    google.charts.load('current', {'packages':['timeline'], callback: testSession }); // ADDED IN ITS PLACE
    });

    function testSession() {
      if(sessionStorage.getItem("drop") == null) {
        google.script.run.withSuccessHandler(buildDropDowns).buildDropDowns();
      } else {
        buildDropDowns(sessionStorage.getItem("drop"));
      }

      if(sessionStorage.getItem("chart") == null) {
        google.script.run.withSuccessHandler(getChartData).getChartData("-", "-", "-", "-", "-", "-", "-");
      } else {
        getChartData(sessionStorage.getItem("chart"));
      }
    }

    function buildDropDowns(JSONObj) {
      sessionStorage.setItem("drop", JSONObj);
      var dropDownObj = JSON.parse(JSONObj);
      // do a bunch of things with the dropDownObj
    }

    function getChartData(JSONObj) {
      sessionStorage.setItem("chart", JSONObj);
      var dataObj = JSON.parse(JSONObj);
      var rawChartData = dataObj.chartData;
      var count = dataObj.count;
      var colors = dataObj.colors;
      const dateIndices = [3,4];
      const chartData = rawChartData.map(function (row) {
        return row.map(function (col, index) {
          return (dateIndices.indexOf(index) === -1) ? col : new Date(col);
        });
      });
      if(chartData.length == 1) {
        document.getElementById("chartDiv").innerHTML = "<b>No projects meet your criteria</b>";
      } else {
        buildChart(chartData, count, colors);
      }
    }
    
    //google.charts.load('current', {'packages':['timeline']});  //COMMENT OUT NOW
      
    function buildChart(chartData, count, colors) {
      var container = document.getElementById('chartDiv');

      //*** EDIT - THIS APPEARS TO BE PROBLEM LINE ***
      var chart = new google.visualization.Timeline(container);
      //Is there something about visualizations that are different on a reload?

      var dataTable = new google.visualization.DataTable();
        
      dataTable.addColumn({ type: 'string', id: 'Project' });
      dataTable.addColumn({ type: 'string', id: 'dummy bar label' });
      dataTable.addColumn({ type: 'string', role: 'tooltip', p: {'html':true}});
      dataTable.addColumn({ type: 'date', id: 'Start' });
      dataTable.addColumn({ type: 'date', id: 'End' });
      dataTable.addColumn({ type: 'number', id: 'sortValue' });
      dataTable.addColumn({ type: 'string', id: 'gate' });
        
      dataTable.addRows(chartData);
      
      var options = {
        height: Math.min(800, (chartData.length*45)+60),
        width:"100%",
      };
      
      var view = new google.visualization.DataView(dataTable);
      view.setColumns([0, 1, 2, 3, 4]);  // exclude column 5 (sequence)
      
      chart.draw(view, options);
     
    }

现在我在页面加载时加载可视化包,然后才在需要时调用服务器以获取数据,或者如果数据已经在 sessionData 中则显示数据,一切似乎都在按我想要的方式进行到.