JJAbrams
JJAbrams

Reputation: 25

'undefined' error even after JSON.parse

<!DOCTYPE html>
<html>

<head>
  <title>Imagery Gallery</title>
</head>

<body>
  <h2>Location List</h2>

  <!-- image gallery will be displayed in the results <div> -->
  <div id="results"></div>


  <!-- JavaScript codes -->
  <script src="HTTPRequest.js"></script>
  <script>
    //Send request to the server to get the JSON dataset showing the list of locations
    //The URL to request is "http://geopingyin.com/gis/Locations.php"
    //The request function sendHttpRequest(sURL) is defined in the HTTPRequest.js file
    sendHttpRequest("http://geopingyin.com/gis/Locations.php");

    //When the JSON dataset (JSONData, a text string) is successfully returned to the browser,
    //The function handleResponseData(JSONData) will be automatically called.
    //Complete the following function to process the JSON dataset.
    function handleResponseData(JSONData) {
      var obj = JSON.parse(JSONData);
      for (i in obj) {
        i += obj[i] + "<br>";
        document.getElementById("results").innerHTML = i.Locations;

      }

    }

    //place your codes here for the imagery gallery
  </script>
</body>

</html>

This code is giving me an 'undefined' answer whenever I run it. After lots of research it seems like most people have issues with 'undefined' because they are using strings and not objects. However in my code I used a JSON.parse in order to create an object off of the original string, and it still comes up as undefined. I wish to use JSON.parse in order to change my array into objects and then loop through and display each one, yet I can not seem to figure out how to go about this. Any help would be greatly appreciated!

Also here is my HTTPRequest.js code just in case

var xmlHttp = createHttpRequestObj(); //Http request object

//Create HTTP request object
function createHttpRequestObj() {
  var xmlHttpObj;
  if (window.XMLHttpRequest) {
    // code for IE7+, Firefox, Chrome, Opera, Safari
    try {
      xmlHttpObj = new XMLHttpRequest();
    } catch (e) {
      xmlHttpObj = false;
    }
  } else {
    // code for IE6, IE5
    try {
      xmlHttpObj = new ActiveXObject("Microsoft.XMLHTTP");
    } catch (e) {
      xmlHttpObj = false;
    }
  }

  if (!xmlHttpObj)
    alert("Cannot create the Http request object");
  else {
    return xmlHttpObj;
  }
}

//Send HTTP request with the URL
//Function handleServerResponse() will be used to interpret the response 
function sendHttpRequest(sURL) {
  if (xmlHttp.readyState == 0 || xmlHttp.readyState == 4) {
    xmlHttp.open("GET", sURL, true);
    xmlHttp.onreadystatechange = handleServerResponse;
    xmlHttp.send();
  } else {
    setTimeout(function() {
      sendHttpRequest(sURL);
    }, 1000);
  }
}

//Handel HTTP response
function handleServerResponse() {
  if (xmlHttp.readyState == 4) {
    if (xmlHttp.status == 200) {
      xmlResponse = xmlHttp.responseText;

      //Handle the xmlResponse
      handleResponseData(xmlResponse);
    }
  }
}

THANK YOU!

Upvotes: 2

Views: 1844

Answers (1)

Daniel Beck
Daniel Beck

Reputation: 21485

undefined results when you try to access data that doesn't exist. This can result from trying to read an object key from what is actually a string; but can equally happen when reading a nonexistent key from a real object (which is one part of what was going wrong in your code.)

The issues are within your handleResponseData function; I've commented it below to describe what's going wrong:

function handleResponseData(JSONData) {
  var obj = JSON.parse(JSONData); // so far so good

  /* obj only contains one key, "Locations", so `obj` isn't 
     what you want to be iterating over; instead you want to iterate
     within obj.Locations: */
  for (i in obj) { 
    /* Two problems in this next line: first, it's trying to 
       concatenate objects onto a string (which will result in 
       the string "[object Object]"); second, it's trying to 
       concatenating them onto the iterator, which would
       interfere with the loop: */
    i += obj[i] + "<br>";  

    /* This line should not be inside the loop, and it shouldn't be
       trying to read the Locations key from child objects, because
       that key was on the parent: */
    document.getElementById("results").innerHTML = i.Locations;
  }
}

Below is a corrected version (I've assumed the .Name key from each object within the Locations array is what you want):

var xmlHttp = createHttpRequestObj();
function createHttpRequestObj() {
  // Code for handling obsolete browsers omitted for brevity
  return new XMLHttpRequest();
}

function sendHttpRequest(sURL) {
  if (xmlHttp.readyState == 0 || xmlHttp.readyState == 4) {
    xmlHttp.open("GET", sURL, true);
    xmlHttp.onreadystatechange = handleServerResponse;
    xmlHttp.send();
  } else {
    setTimeout(function() {
      sendHttpRequest(sURL);
    }, 1000);
  }
}

function handleServerResponse() {
  if (xmlHttp.readyState == 4) {
    if (xmlHttp.status == 200) {
      xmlResponse = xmlHttp.responseText;
      handleResponseData(xmlResponse);
    }
  }
}

sendHttpRequest("https://geopingyin.com/gis/Locations.php");

function handleResponseData(JSONData) {
  var obj = JSON.parse(JSONData);
  var output = "";
  for (i in obj.Locations) {
    output += obj.Locations[i].Name + "<br>";
  }
  document.getElementById("results").innerHTML = output
}
<h2>Location List</h2>
<div id="results"></div>

Upvotes: 2

Related Questions