开发者问题收集

.ajax JSON TypeError:无法读取未定义的属性“长度”

2016-09-01
3796

我正在使用一个 HTML 页面,该页面有两个输入框,分别用于输入出发地和目的地地址。

当用户提交条目(单击按钮)时,我会使用一些 JavaScript 捕获这些条目。响应是来自 Googlemaps Distance Matrix API 的 JSON。

我无法提取持续时间和距离的值,因为它们的嵌套方式我(显然)无法理解。

当我输入数据并启动脚本时,我得到了:

TypeError: Cannot read property 'length' of undefined

我确信输入框被正确捕获,因为我得到了我想要的响应并将其打印到控制台。我想获取持续时间和距离值,以便我可以将它们显示在 HTML 中。

在其他地方阅读有关此错误的信息后,我明白(我认为)我没有正确定义 origins ,但不知道如何解决这个问题。

我希望有人可以帮助我实现此功能,并建议如何在 HTML 上的 div 中显示距离和持续时间值。

这是我的 javascript:

$(document).ready(function() {
  console.log("ready!");

  $('#try-again').hide();

  // on form submission ...
  $('form').on('submit', function() {

    console.log("the form has beeen submitted");

    // grab values
    origin = $('input[name="origin"]').val();
    destination = $('input[name="destination"]').val();
    console.log(origin, destination)

    $.ajax({
      type: "POST",
      url: "/",
      data : { 'origin': origin, 'destination': destination },
      success: function(data) {
        var origins = data.originAddresses;
        var destinations = data.destinationAddresses;
        for (var i = 0; i < origins.length; i++) {
          var results = data.rows[i].elements;
          for (var j = 0; j < results.length; j++) {
            var element = results[j];
            var distance = element.distance.text;
            var duration = element.duration.text;
            var from = origins[i];
            var to = destinations[j];
          }
        }
       console.log(distance, duration);
      },
      error: function(error) {
        console.log(error)
      }
    });

  });

  $('#try-again').on('click', function(){
    $('input').val('').show();
    $('#try-again').hide();
    $('#results').html('');
  });

}); 

这是我正在使用的 JSON 响应结构:

{
  "originAddresses": [ "Greenwich, Greater London, UK", "13 Great Carleton Square, Edinburgh, City of Edinburgh EH16 4, UK" ],
  "destinationAddresses": [ "Stockholm County, Sweden", "Dlouhá 609/2, 110 00 Praha-Staré Město, Česká republika" ],
  "rows": [ {
    "elements": [ {
      "status": "OK",
      "duration": {
        "value": 70778,
        "text": "19 hours 40 mins"
      },
      "distance": {
        "value": 1887508,
        "text": "1173 mi"
      }
    }, {
      "status": "OK",
      "duration": {
        "value": 44476,
        "text": "12 hours 21 mins"
      },
      "distance": {
        "value": 1262780,
        "text": "785 mi"
      }
    } ]
  }, {
    "elements": [ {
      "status": "OK",
      "duration": {
        "value": 96000,
        "text": "1 day 3 hours"
      },
      "distance": {
        "value": 2566737,
        "text": "1595 mi"
      }
    }, {
      "status": "OK",
      "duration": {
        "value": 69698,
        "text": "19 hours 22 mins"
      },
      "distance": {
        "value": 1942009,
        "text": "1207 mi"
      }
    } ]
  } ]
}
3个回答

我怀疑您的 ajax 调用返回的数据不完整、为空或存在问题。我会将您的循环包装在一个 guard 语句中并检查未定义,如下所示:

success: function(data) {
    var origins = data.originAddresses;
    var destinations = data.destinationAddresses;
    if (typeof origins !== "undefined") {
        for (var i = 0; i < origins.length; i++) {
          var results = data.rows[i].elements;
          for (var j = 0; j < results.length; j++) {
            var element = results[j];
            var distance = element.distance.text;
            var duration = element.duration.text;
            var from = origins[i];
            var to = destinations[j];
          }
        }
    }
    console.log(distance, duration);
},
Justin Herter
2016-09-01
success: function(data) {
    var origins = data.originAddresses;
    var destinations = data.destinationAddresses;
    if(!origins || !destinations){return;}
    for (var i = 0; i < origins.length; i++) {
      if(!data.rows){continue;}
      var results = data.rows[i].elements;
      if(!results){continue;}
      for (var j = 0; j < results.length; j++) {
        var element = results[j];
        var distance = element.distance.text;
        var duration = element.duration.text;
        var from = origins[i];
        var to = destinations[j];
      }
    }
   console.log(distance, duration);
  }

检查从数据获取的每个对象或数组是否未定义

Romain De Sa Jardim
2016-09-01

也许可以尝试使用不同的解析方法。我喜欢使用:

var d = $.parseJSON(data);   

此外,此代码似乎在 jsfiddle 上有效:

if  (d.originAddresses) {
  for (var i = 0; i < d.originAddresses.length; i++) {
    if (d.rows) {
      var row = d.rows[i];
      var element = row.elements[i];

      console.log(d.originAddresses[i]);
      console.log(d.destinationAddresses[i]);
      console.log(element.distance.value);
      console.log(element.distance.text);
    }
  }
}

正如其他人提到的。如果 API 返回无效数据,进行一些 null/undefined 检查可能是一个好主意。

Jay Tomten
2016-09-01