nacc nacc - 3 months ago 12
Ajax Question

.ajax JSON TypeError: Cannot read property 'length' of undefined

I'm working with an HTML page that has two input boxes for an origin and destination address.

When the user submits the entries (on a button click) I am capturing those using some JavaScript. The response is JSON from the Googlemaps Distance Matrix API.

I'm having trouble getting values extracted for duration and distance as they're nested in a manner I'm not (apparently) capable of wrapping my head around.

When I input data and fire off the script I am getting:


TypeError: Cannot read property 'length' of undefined


I am confident the input boxes are being captured appropriately as I get the response I intended and can print it to console. I would like to get the duration and distance values so that I can display them in the HTML.

After reading about this error elsewhere I understand (I think) that I'm not properly defining
origins
but can't figure out how to get around it.

I'm hoping someone can help me get this function working and suggest how I might go about displaying the distance and duration values in a div on my HTML.

Here is my 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('');
});

});


And here is the JSON response structure I'm working with:

{
"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"
}
} ]
} ]
}

Answer

I suspect that the data returned from your ajax call is incomplete, empty, or something is amiss there. I would wrap your loop in a guard statement and check for undefined like so:

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);
},
Comments