不断收到TypeError:无法读取未定义的属性'formatted_address'

时间:2019-08-15 13:00:24

标签: javascript google-api axios geocoding google-geocoding-api

我已经创建了一个页面,可以在其中批量粘贴地址,并通过Google Geocoding API和axios对地址进行地理编码。大多数地址都转换为相应的纬度和经度,但是当我在开发人员控制台中签入时,某些地址会得到“ TypeError:无法读取未定义的属性'formatted_address'”。 'formatted_address'是JSON响应中的完整地址。

<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
  <title>Geocoder</title>
</head>

<body>
<div class = "container">

  <!--User input stuff -->
  <br>
  <h3 id = "text-center"> <font color="black"> enter locations: </font></h3>
  <br>
  <form id = "location-form">
    <textarea id = "location-input" rows= 20 class="form-control form-control-lg"> </textarea>
    <br>
    <button type="submit" class="btn btn-primary btn-block"> Submit </button>
  </form>

  <!-- divs for the formatted address & lat and long -->
  <div class="card-block" id="formatted-address"> </div>
  <div class="card-block" id="geometry"> </div>
  <table class="table" id="output-table">
    <thead>
    <tr>
      <th scope="col"> Address </th>
      <th scope="col"> Latitude </th>
      <th scope="col"> Longitude </th>
    </tr>
  </thead>
</table>

<!-- <h7 id = "row-count">Row count</h7> -->

<center> <button type="button btn-primary" class="btn btn-primary" onclick="exportTableToExcel('output-table', 'Geocode-Output')">Export Table Data To Excel File</button> </center>


</div>

  <script>
    alert("Enter the addresses, one address per line, seperated by a comma.")
    //Get the data from the user's input.
    var locationForm = document.getElementById('location-form');
    //Add an event listener which checks if submit is pressed. Once it is, run geocode function
    locationForm.addEventListener('submit', geocode);


    /*Handles the sending of requests to the Google Geocode API, and provides functionality for
    * responding to the API requests.
    */
    function geocode(e) {
      e.preventDefault();
      var location = document.getElementById('location-input').value; //raw data
      //Split the user input into a large array
      var locationArray = location.split(',');
      console.log("There are " + locationArray.length + "  elements in the locationArray");

    for (var i = 0; i < locationArray.length; i++) {
      axios.get('https://maps.googleapis.com/maps/api/geocode/json', {
        params:{
          address:locationArray[i],
          key:'Censored'
        }
      })

      .then(function(response){
        var address = response.data.results[0].formatted_address;
        var lat = response.data.results[0].geometry.location.lat;
        var lng = response.data.results[0].geometry.location.lng;

        var outputTable = document.getElementById('output-table');
        var newRow = outputTable.insertRow(outputTable.rows.length);

        newRow.innerHTML = '<tr><td>' + address + '<tr><td>' + lat + '<tr><td>' + lng;

        console.log(lat);
        console.log(lng);
      })

      //Handle errors
      .catch(function(error){
        console.log(error);
      });
    }
  }

  function exportTableToExcel(tableID, filename) {
    var downloadLink;
    var dataType= 'application/vnd.ms-excel';
    var tableSelect = document.getElementById(tableID);
    var tableHTML = tableSelect.outerHTML.replace(/ /g, '%20');

    //Specify the filename
    filename = filename?filename+'.xls':'excel_data.xls';

    //create download link element
    downloadLink = document.createElement("a");

    document.body.appendChild(downloadLink);

    if(navigator.msSaveOrOpenBlob){
      var blob = new Blob(['\ufeff', tableHTML], {
        type: dataType
      });
    navigator.msSaveOrOpenBlob( blob, filename);
      } else {
    // Create a link to the file
    downloadLink.href = 'data:' + dataType + ', ' + tableHTML;
    //Setting the file filename
    downloadLink.download = filename;
    //triggering the function
    downloadLink.click();
    }
  }
  </script>

</body>
</html>

错误发生在“变量地址= response.data.results [0] .formatted_address;”

1 个答案:

答案 0 :(得分:0)

您应该注意,Geocoding API网络服务可以返回不同的状态作为响应。如果一切正常,您将获得“ OK”状态,并且在这种情况下response.data.results[0]不会被未定义,对于其他状态,结果数组为空,因此您没有索引为0的元素。

查看文档中可能状态的完整列表:

https://developers.google.com/maps/documentation/geocoding/intro#StatusCodes

请参阅您的代码,然后检查并处理响应的状态字段。

axios.get('https://maps.googleapis.com/maps/api/geocode/json', {
    params:{
        address:locationArray[i],
        key:'Censored'
    }
}).then(function(response) {
    //First check status
    const status = response.data.status;
    if (status==="OK") { 
        var address = response.data.results[0].formatted_address;
        var lat = response.data.results[0].geometry.location.lat;
        var lng = response.data.results[0].geometry.location.lng;

        var outputTable = document.getElementById('output-table');
        var newRow = outputTable.insertRow(outputTable.rows.length);

        newRow.innerHTML = '<tr><td>' + address + '<tr><td>' + lat + '<tr><td>' + lng;

        console.log(lat);
        console.log(lng);
    } else if (status==="ZERO_RESULTS") {
        //Handle zero results here
    } else if (status==="OVER_QUERY_LIMIT") {
        //Handle over query per second limit using exponential back off here 
    } else if (status==="REQUEST_DENIED") {
        //Handle request denied here
    } else if (status==="INVALID_REQUEST") {
        //Handle invalid request here
    } else if (status==="UNKNOWN_ERROR") {
        //Handle server error here
    }
})
//Handle errors
.catch(function(error){
    console.log(error);
});

我希望这会有所帮助!