Jooyeong Kang
Jooyeong Kang

Reputation: 13

How to load JSON from URL and display by using plain javascript on HTML page?

I'm trying to get JSON data from the specific URL and display it on the HTML page to check whether it works or not. I have no idea about what is wrong and I should fix on my code.

<script>
        var jsonDoc="";
        function loadJSON(url){
            //alert(url);
            var request = new XMLHttpRequest();

            request.open('GET', url, false);
            request.responseType = 'json';
            request.onreadystatechange = function(){
                if(request.readyState == 4 && request.status == 200){
                    jsonDoc = JSON.parse(request.responseText);
                }else{
                    jsonDoc = null;
                }

                request.send();

            };
        }
        document.getElementById('content').innerHTML = jsonDoc;
</script>

<body>
    <h1>Enter URL for Highest-grossing films List JSON File</h1>
    <form>
        <input type="text" id="url" value=""><br>
        <input type="button" name="submit" value="Submit Query" onclick="loadJSON(document.getElementById('url').value)">
    </form>

    <div id="content"></div>
</body>

Upvotes: 1

Views: 3396

Answers (3)

John Wooten
John Wooten

Reputation: 745

I may be off base here, but the main thing I thought was wrong in your approach was that the input text field did not have a 'name' field. I made some changes in your code so that I could track down a way to get the value of that name field out to look at its value. This may not be what you wanted, but it gives a way to find your parameters and you can then do with them as you wish. Here is the modified code with a couple of simple javascript functions to assist:

<html>
<head>
<script>
function getURLParameters(paramName)
{
    var sURL = window.document.URL.toString();
    alert('sURL = ' + sURL);
    if (sURL.indexOf("?") > 0)
    {
        var arrParams = sURL.split("?");
        var arrURLParams = arrParams[1].split("&");
        var arrParamNames = new Array(arrURLParams.length);
        var arrParamValues = new Array(arrURLParams.length);

        var i = 0;
        for (i = 0; i<arrURLParams.length; i++)
        {
            var sParam =  arrURLParams[i].split("=");
            arrParamNames[i] = sParam[0];
            if (sParam[1] != "")
                arrParamValues[i] = unescape(sParam[1]);
            else
                arrParamValues[i] = "No Value";
        }

        for (i=0; i<arrURLParams.length; i++)
        {
            if (arrParamNames[i] == paramName)
            {
                alert("Parameter:" + arrParamValues[i]);
                return arrParamValues[i];
            }
        }
        return "No Parameters Found";
    }
}
 function printDiv(divName) {
     alert('In printDiv with divName '+divName);
     var printContents = document.getElementById(divName).innerHTML;
     var originalContents = document.body.innerHTML;

     var replyStr = "Post parameters for 'dest':\r\n" + getURLParameters('dest'); // "1234";
     alert(replyStr);
     document.write(replyStr);
//     document.body.innerHTML = replyStr;
}
</script>
</head>
<body>
    <h1>Enter URL </h1>
    <form >
        <input type="text"  name="dest" value=""/><br/>
        <br />
        <input type="submit" name="submit" value="Submit Query" onClick="return(printDiv('printableArea'))"/>
    </form>

    <div id="content"></div>
    <div id="printableArea">
      <h1>Print me</h1>
</div>

</body>
</html>

I was going to put the response back into the printableAres innerHTML, but got it to write out and stopped there. Main changes were to add a name 'dest' to the textfield that received the URL, and process the form data using getURLParams for the field value for 'dest'. You can probably work out what you wanted to do from here. Hope this helps.

Upvotes: 0

lima_fil
lima_fil

Reputation: 1771

Add it to the DOM after response is received.

request.onreadystatechange = function() {
  // here
};

Also move request.send(); outside of request.onreadystatechange callback:

    var jsonDoc="";
    function loadJSON(url){
        //alert(url);
        var request = new XMLHttpRequest();

        request.open('GET', url, false);
        request.responseType = 'json';
        request.onreadystatechange = function(){
            if(request.readyState == 4 && request.status == 200){
                jsonDoc = JSON.parse(request.responseText);
                document.getElementById('content').innerHTML = jsonDoc;
            }else{
                jsonDoc = null;
            }
        };
        request.send();
    }

Upvotes: 0

Onel Harrison
Onel Harrison

Reputation: 1334

There are a number of errors preventing your code from doing what you want it to do.

  1. You are trying to access the element that has the content id before the element is loaded on the page. Think of it like this. Your script and body elements are organized in such a way that your script will load and execute first before the body element and its children are loaded.

    The culprit is this line: document.getElementById('content').innerHTML = jsonDoc.

    It belongs in the onreadystatechange function because you only want to update content when you have received the data from the API.

    If you move that line to the onreadystatechange function, you now have access to the data you retrieved from the API and do not need the jsonDoc global variable.

  2. The request.responseType = 'json' code raises this descriptive error.

    InvalidAccessError: synchronous XMLHttpRequests do not support timeout and responseType.

    Delete that line of code because it is attempting an operation that is not allowed.

  3. You are never sending a request because request.send() is inside the code that handles the API's response. It should be outside that function.

  4. In the onreadystatechange function, you will also want to JSON.stringify the data after using JSON.parse to make it into the string you want to display.

After fixing all of that, your JavaScript should look similar to this.

<script>
  function loadJSON(url) {
    let request = new XMLHttpRequest();

    request.open('GET', url, false);
    request.onreadystatechange = function() {
      if (request.readyState == 4 && request.status == 200) {
        const data = JSON.parse(request.responseText);
        document.getElementById('content').innerHTML = JSON.stringify(data);
      }
    };
    request.send();
  }
</script>

A more modern JavaScript practice is to use the fetch API. It makes fetching data from APIs a lot easier. Here is the equivalent of the code above, using the fetch API.

<script>
  function loadJSON(url) {
    fetch(url)
      .then(function(res) { return res.json(); })
      .then(function(data) {
         document.getElementById('content').innerHTML = JSON.stringify(data);
      });
  }
</script>

You can read more about using the Fetch API on MDN.

Upvotes: 1

Related Questions