3

Hi i am using this code for my AJAX JSON request but for some if i try to make jsonObj a global variable and console.log() it always comes up as undefined in the debugger console

To clarify my question, how can I retrieve a global variable from an AJAX JSON request

function loadJSON() {
  var data_file = "https://www.tutorialspoint.com/json/data.json";
  var http_request = new XMLHttpRequest();
  try {
    // Opera 8.0+, Firefox, Chrome, Safari
    http_request = new XMLHttpRequest();
  } catch (e) {
    // Internet Explorer Browsers
    try {
      http_request = new ActiveXObject("Msxml2.XMLHTTP");

    } catch (e) {

      try {
        http_request = new ActiveXObject("Microsoft.XMLHTTP");
      } catch (e) {
        // Something went wrong
        alert("Your browser broke!");
        return false;
      }

    }
  }

  http_request.onreadystatechange = function() {

    if (http_request.readyState == 4) {
      // Javascript function JSON.parse to parse JSON data
      var jsonObj = JSON.parse(http_request.responseText);

      // jsonObj variable now contains the data structure and can
      // be accessed as jsonObj.name and jsonObj.country.
      document.getElementById("Name").innerHTML = jsonObj.name;
      document.getElementById("Country").innerHTML = jsonObj.country;
    }
  }

  http_request.open("GET", data_file, true);
  http_request.send();
}
<h1>Cricketer Details</h1>

<table class="src">
  <tr>
    <th>Name</th>
    <th>Country</th>
  </tr>
  <tr>
    <td>
      <div id="Name">Sachin</div>
    </td>
    <td>
      <div id="Country">India</div>
    </td>
  </tr>
</table>

<div class="central">
  <button type="button" onclick="loadJSON()">Update Details </button>
</div>

4
  • Using the code you provided it seems to work as expected - see demo here. Can you be more specific about WHY you need the json data to be a global variable? Commented Sep 14, 2017 at 5:21
  • Likely a duplicate of stackoverflow.com/questions/14220321/… Commented Sep 14, 2017 at 5:33
  • I changed your code to use https and it worked as written Commented Sep 14, 2017 at 5:33
  • Please see my answer for the right way of achieving the functionality you need. Commented Sep 14, 2017 at 5:43

3 Answers 3

2

The best way to approach this is by using what's called a callback function. A callback function is a function that is invoked when specific event takes place. In your case that event is the data being retrieved from your JSON endpoint (URL).

The proper way to do this is to create a function that will be called when your data is received and will then carry out the remaining logic. If you want to make that data also accessible globally, part of the callback function can update your global variable.

In the updated code below we first declare a global variable globalJSON that holds our data. Before you receive any data (i.e. before you click the button) the value of globalJSON.data will be null. Once the data is received the callback function updateView() is called with the received data. Inside of updateView() we update the global variable globalJSON.data and carry out the remaining logic (i.e. updating the required HTML elements).

You can then use globalJSON.data anywhere else in your code to get the data received when Update Details button was clicked.

// declare your global variable that will get updated once we receive data

var globalJSON = {
    data: null
}

// this gets executed the moment you load the page - notice the value is null

console.log(globalJSON.data);

// this gets executed AFTER you receive data - notice call to updateView() inside AJAX call function

function updateView(data) {
    // this will update the value of our global variable
    
    globalJSON.data = data;
    
    // this is the rest of the logic that you want executed with the received data
    
    document.getElementById("Name").innerHTML = data.name;
    document.getElementById("Country").innerHTML = data.country;
    
    // this will show that the global variable was in fact updated
    
    console.log(globalJSON.data);
}

function loadJSON() {
    var data_file = "https://www.tutorialspoint.com/json/data.json";
    var http_request = new XMLHttpRequest();
    try {
        // Opera 8.0+, Firefox, Chrome, Safari
        http_request = new XMLHttpRequest();
    } catch (e) {
        // Internet Explorer Browsers
        try {
            http_request = new ActiveXObject("Msxml2.XMLHTTP");
        } catch (e) {
            try {
                http_request = new ActiveXObject("Microsoft.XMLHTTP");
            } catch (e) {
                // Something went wrong
                alert("Your browser broke!");
                return false;
            }
        }
    }
    http_request.onreadystatechange = function() {
        if (http_request.readyState == 4) {
            // Javascript function JSON.parse to parse JSON data
            var jsonObj = JSON.parse(http_request.responseText);
            updateView(jsonObj);
            // jsonObj variable now contains the data structure and can
            // be accessed as jsonObj.name and jsonObj.country.
        }
    }
    http_request.open("GET", data_file, true);
    http_request.send();
}
 <h1>Cricketer Details</h1>
		
      <table class = "src">
         <tr><th>Name</th><th>Country</th></tr>
         <tr><td><div id = "Name">Sachin</div></td>
         <td><div id = "Country">India</div></td></tr>
      </table>

      <div class = "central">
         <button type = "button" onclick = "loadJSON()">Update Details </button>
      </div>

Sign up to request clarification or add additional context in comments.

Comments

0

If you just want to access jsonObj from outside of the event handler, explicitly place it on the global scope (regardless of whether this is a good idea) you could create jsonObj on window by window.jsonObj = JSON.parse(http_request.responseText);

But you won't have any way of knowing when it's defined outside of the event handler. However, it would fulfill your requirement of being able to console.log(window.jsonObj) (presumably from the developer console). Also you could just console.log(jsonObj) in the eventhandler if you wanted to see the value.

full code:

<html>
<head>
    <meta content = "text/html; charset = ISO-8859-1" http-equiv = "content-type">

    <script type = "application/javascript">
        function loadJSON(){
            var data_file = "http://www.tutorialspoint.com/json/data.json";
            var http_request = new XMLHttpRequest();
            try{
            // Opera 8.0+, Firefox, Chrome, Safari
            http_request = new XMLHttpRequest();
            }catch (e){
            // Internet Explorer Browsers
            try{
                http_request = new ActiveXObject("Msxml2.XMLHTTP");

            }catch (e) {

                try{
                    http_request = new ActiveXObject("Microsoft.XMLHTTP");
                }catch (e){
                    // Something went wrong
                    alert("Your browser broke!");
                    return false;
                }

            }
            }

            http_request.onreadystatechange = function(){

            if (http_request.readyState == 4  ){
                // Javascript function JSON.parse to parse JSON data
                // if you want to be able to access this property from the developer console
                window.jsonObj = JSON.parse(http_request.responseText);
                // if you just want to see the value
                console.log(JSON.parse(http_request.responseText));
                // jsonObj variable now contains the data structure and can
                // be accessed as jsonObj.name and jsonObj.country.
                document.getElementById("Name").innerHTML = jsonObj.name;
                document.getElementById("Country").innerHTML = jsonObj.country;
            }
            }

            http_request.open("GET", data_file, true);
            http_request.send();
        }

    </script>

    <title>tutorialspoint.com JSON</title>
</head>

<body>
    <h1>Cricketer Details</h1>

    <table class = "src">
        <tr><th>Name</th><th>Country</th></tr>
        <tr><td><div id = "Name">Sachin</div></td>
        <td><div id = "Country">India</div></td></tr>
    </table>

    <div class = "central">
        <button type = "button" onclick = "loadJSON()">Update Details </button>
    </div>

</body>

2 Comments

This doesn't change much as even though you can set the value of the global variable it will not announce its state changing because the AJAX call is asynchronous.
Matt Newelski, I made that point in my answer. I was merely attempting to answer his question without refactoring his code. Thanks!
0

Declare a variable at first like var jsonObj= ''; ( Inside your function. This variable is not global from the page context, but from the function context ). access the variable in your function. A problem in your url that you use http://www.tutorialspoint.com/json/data.json but the original site using https protocol. As a result you got an error something like that

Blocked loading mixed active content "http://www.tutorialspoint.com/json/data.json"

So change the url also to https://www.tutorialspoint.com/json/data.json. Then you can parse the result as you want.

<title>tutorialspoint.com JSON</title>
   
   <body>
      <h1>Cricketer Details</h1>
		
      <table class = "src">
         <tr><th>Name</th><th>Country</th></tr>
         <tr><td><div id = "Name">Sachin</div></td>
         <td><div id = "Country">India</div></td></tr>
      </table>

      <div class = "central">
         <button type = "button" onclick = "loadJSON();">Update Details </button>
      </div>
	  
	  <script>
	  function loadJSON(){
	  var jsonObj= '';
            var data_file = "https://www.tutorialspoint.com/json/data.json";
            var http_request = new XMLHttpRequest();
            try{
               // Opera 8.0+, Firefox, Chrome, Safari
               http_request = new XMLHttpRequest();
            }catch (e){
               // Internet Explorer Browsers
               try{
                  http_request = new ActiveXObject("Msxml2.XMLHTTP");
					
               }catch (e) {
				
                  try{
                     http_request = new ActiveXObject("Microsoft.XMLHTTP");
                  }catch (e){
                     // Something went wrong
                     alert("Your browser broke!");
                     return false;
                  }
					
               }
            }
			
            http_request.onreadystatechange = function(){
			
               if (http_request.readyState == 4  ){
                  // Javascript function JSON.parse to parse JSON data
                  jsonObj = JSON.parse(http_request.responseText);

                  // jsonObj variable now contains the data structure and can
                  // be accessed as jsonObj.name and jsonObj.country.
				  console.log(jsonObj);
                  document.getElementById("Name").innerHTML = jsonObj.name;
                  document.getElementById("Country").innerHTML = jsonObj.country;
               }
            }
			
            http_request.open("GET", data_file, true);
            http_request.send();
         }
	  </script>
		
   </body>

4 Comments

The fact that var jsonObj= ''; sits inside of the loadJSON() declaration does not make it global, since jsonObj won't exists until you actually call loadJSON()
Yes @MattNewelski, you are right. but from the function context, it's somehow can be called global (because you can access the variable within that function)
Nothing more misleading, especially for a beginner, than calling a variable that only exists in the functions local scope a global variable.
Edited my answer. @MattNewelski

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.