JavaScript Object Notation:

JSON allows us to share and structure data across the web. It can be read by APIs and manipulated using any programming language.

It is called JSON because it very much resembles Objects in JavaScript, as we can see if we visit the Star Wars API website:

Star Wars API example 1

We can retrieve this information using cURL, by using the command curl and then typing in the address of the API listing:

Star Wars API example 2

From here of course, we can add the information we're looking for:

Star Wars API C-3PO information

But how can we make this information more readable?

We use the python command and json.tool:

Star Wars API C-3PO information pretty printed

But this information is still in Terminal, or its equivalents. How do we actually retrieve this information and make it available for consumers? We instantiate XMLHttpRequest (or XHR ) a built in JavaScript Object which allows us to call external APIs. It gives us the method to open, send and close connections to APIs.

First, in our .js script we set a variable and assign it a new instance of the XMLHttpRequest


in our HTML we create a <div> with id="data".

Beneath this entire explanation is a <div> with that id where the result will be displayed. Click here to go there directly.


Back in the JavaScript file, we now create a function that checks for changes in the state of our variable:

To explain the code:

We create a new xhr.onreadystatechange(), and whenever the state changes of our xhr Object, we want to run a check. If the ready state is equal to 4 and the status is 200, then what we want to do is use JavaScript to do document.getElementByID() and retrieve our data div. And then we're going to change the innerHTML to be equal to the response text that comes back from our xhr object.

Now we have our listener in place, we need to open() a connection to the API and then send() for that information:

Click to see the results

But the results are still not very readable to humans, and they are a "string instead of an Object. You can see so by opening console. So now we will use the JSON parse() method to make them so.

Open console then click to see the results

We would expect from here to be able to create a variable and then call that variable to show the results, but we cannot. So how do we get the results?

We can create such a variable and call it from within the xhr.onreadystatechange function, but that would mean we would always have to contain our code within that function. This is not ideal. So, we need to find a way to access what is inside the function and make it available outside of that function.

We can create another (callback) function and pass the data into it (the new lines of code are indicated with "-->"):

Again, however, we would only be making the data available inside this function. Again, this is not ideal.

So how do we make the data available outside of the function?

We can use either setTimeout() or callback() functions.

But first, lets examine what is happening inside the code:


  1. setTimeout():
  2. The setTimeout() function allows us to tell our application to stop executing for a period of time, through the use of a second argument. Again, the new code is indicated with "-->" in the code block below:

    We added a second argument to the new function setTimeout(), that being 500. This tells the function to stop logging to the console for 500 milliseconds, which effectively gives the xhr.onreadystatechange() time to execute before the data is logged.

    Open console then click to see the results

    This means we can get rid of the setData() function and set data = JSON.parse(this.responseText inside the xhr.onreadystatechange() function:

    However, the problem with setTimeout() functions is that not all networks run at the same speed. Nowadays, most of people in cities have fibre-optic connections that run at high speed, but this is not universal - rural areas still use broadband, while some still use dial-up.


    So, we need a different, more robust solution, which is the callback() function:


  3. Callback
  4. Since everything in JavaScript is an Object, it follows that funtions() are Objects. Because of this, a function() can be passed to another function() as an argument. This means effectively that we can call data from one function() by calling the other function().

    So, let's now rewrite our code as a function():

    And create our callback function:

    Now, we add in the argument and tell the code to execute to the console:

    Above, we have added the argument cb to the function getData(). We are telling the lower lines of code (getData(function(data){}); to act as the conduit for cb in the first line of code.

    Perhaps a more elegant solution is to write a separate function instead of using getData() as a function with data as an argument. To do this, we delete the getData(function(data) function and write a new function called printDataToConsole. Then, beneath, we tell the code to execute with printDataToConsole as an argument to the getData() function:


    The entire code block now reads:

    Open console then click to see the results

But we still cannot see the results on the page. We'll cover that next.