AJAX and JSON

In this lesson we will introduce and discuss both Asynchronous JavaScript and XML (AJAX) and JavaScript Object Notation (JSON).

Ajax

Ajax allows us to request and retrieve information from the server without refreshing the webpage.

The new object we will discuss is XMLHTTPRequest (shorted to XHR in most documentation) and some of its associated methods. Note you can retrieve more than XML with this request object despite its name, and can be used for more than just web servers as well.

To use this, we start by creating a new XHR object, set up an event handler for when the request completes using the onreadystatechange property, we specify what we want to do, and where we want to do it usign the open method, then tell it to do it using the send. To discuss this further, it is quicker to give an example and then work through it.



function retrieveValue(){

  // Create a new XMLHttpRequest Object (the core of Ajax)
  var xhttp = new XMLHttpRequest();

  // Define what will happen when the information is received back from
  // the page that we called.  Remember that we will always be doing
  // Ajax calls asynchronously (meaning we don't just sit there and
  // wait for the response back from the server as that would kill
  // the user experience).  When a response is received from the website
  // And that response has a code of 200 (success) then we have received
  // the final response from the URL we called.
  xhttp.onreadystatechange = function() {

    // We have received all of the information back from the URL
    // And the page told us it was successful.
    if (this.readyState == 4 && this.status == 200) {

       // The results from the URL we called are returned in the
       // STRING xhttp.responseText. In most cases we will need to process that
       // string to make the information useful.  If the string
       // was a JSON encoded string, you should use JSON.parse()

       // In this example, we are placing the results into the HTML
       // tag identified by "demo"
       document.getElementById("demo").innerHTML = xhttp.responseText;
    }
  };

  // Inform the XMLHttpRequest object that we want to use the GET method
  // calling the URL generateContent.php (in the same folder as current code), and that we want the
  // connection to be performed asynchronously (the true), this will
  // ALWAYS be set to true, otherwise your users web page will be unresponsive.
  xhttp.open("GET", "generateContent.php", true);

  // Send the request to the URL, and when the response is received, the
  // onreadystatechange function we defined above will be called.
  xhttp.send();
}
  

The above code sends a request to get a resource (generateContent.php) from a webserver and update the page after the page had loaded. In this case, we got some text from the server and if everything worked correctly that text should appear here →

If the above did not work (there was not text in bold after "here"), press F12 to see the error for why: there are security implications in how your browser and server are setup. In particular, by default, AJAX requests need to be made for URLs in the same domain as the requester, otherwise they fail. However, there are ways to set up the server script to make its data available to any website.

We can easily update the onreadystatechange function to call other functions that we build to create more substantial changes to our pages, including updating tables on the fly with new information.

Review the Mozilla documentation or w3schools.com documentation for a complete description of this function.

We used the onreadystatechange function above, which works as it is supported in all web browsers, but you could also use the onload, onerror, onprogress events, these just don't currently have guaranteed support across the browsers. See Mozilla: Using XMLHttpRequest and Mozilla: XMLHttpRequestEventTarget for more gory details.

JavaScript Objects

Back in the JavaScript lesson, we spoke briefly about JavaScript having objects. JavaScript objects are mainly containers for properties and methods, specified as name:value pairs (see w3schools for more information). NOTE: Sometimes objects are said to have name:value pairs, other times it is said they have attribute:value pairs. The two are equivalent.

To declare a simple object in JavaScript we use braces on the outside with comma separated name:value pairs inside.

var temp = {tool:"wrench"}
This creates for us an object with the name temp that contains the property tool, which happens to have the value of "wrench" currently. To access the peoperties (and methods) of an object, we use the dot notation objectVariable.propertyName
window.alert(temp.tool)

More complex object structures can be defined as well, such as:

var mycar = {color:"blue",wheels:4, engine:{cylinders:6,size:3.7}, available_colors:[“red”,”blue”,”white”]};
This creates an object that contains one string, one number, an object, and an array, showing that values can be complex. You can also create methods that are attached to objects but that is a bit beyond the scope of this lecture (see here if you are interested).

As a note, the JavaScript object does not have to be defined on one line. It can be defined in a more reader friendly style like this:

var mycar = {color:"blue",
    wheels:4,
    engine:{
        cylinders:6,
        size:3.7
    },
    available_colors:[“red”,”blue”,”white”]
};

JavaScript Object Notation(JSON)

JavaScript Object Notation (JSON) is a defined way to serialize and de-serialize data that was originally based on a subset of JavaScript but is now being used all over due to its simplicity and compactness. (See here for more information). Here is an example:

{"ip":"98.207.254.136"}
The syntax looks very much like the syntax to declare an object in JavaScript, and now you know why. JSON's use has grown well past just JavaScript. It has been implemented in most generally used programming languages because it was found to be a fairly lightweight, fairly easy to read by humans, and flexible method for transferring data between a web browser and a web server. JSON has practically eliminated the use of XML for such tasks in web applications. More examples are located here.

JSON and JavaScript

Now that we have covered both JavaScript objects and JSON, we are ready to us the two of them together. There are two functions built into JavaScript that we can use to deal with JSON.

The first one is JSON.stringify(), which converts a JavaScript object into a JSON string and returns it. Here is an example:

var myobj = {closet:{sides:{back:{shelves:{upper:"empty luggage"}}}}};
var myobjstring = JSON.stringify(myobj);
If this code is run, the string that is returned is a JSON string and it happens to be:
"{"closet":{"sides":{"back":{"shelves":{"upper":"empty luggage"}}}}}"
For more details, click here or here.

The second function we will examine is JSON.parse(), which converts a JSON string into a JavaScript object and returns it. Here is an example:

var mynewobj = JSON.parse('{"closet":{"sides":{"back":{"shelves":{"upper":"empty luggage"}}}}}');
If this code is run, the object that is returned is populated with the values specified in the JSON string. Again, for more information see here or here.

Practice problems

  1. Consider the HTML document and the getHints.php script shown below. Write the showHint() JavaScript function to display in the field with id "txtHint" all the hints matching the entered string, if the entered string is not empty, or to display the empty string if the entered string is empty. The showHint(name) function gets the hints by using AJAX to call the getHints.php script with the get parameter named "q" and the value name (if name is not empty). (Think about the URL format if you want to send a GET parameter to a script).
    
    <!DOCTYPE html>        
    <html lang = "en">
      <head>
        <meta charset = "utf-8"><title>AJAX ex</title>
        <script>
        </script>
      </head>
      <body>
        <p><b>Start typing a name in the input field below:</b></p>
        <form>
          First name: <input type="text" onkeyup="showHint(this.value)">
        </form>
          Suggestions: <span id="txtHint"></span>
      </body>
    </html>
            
    The code for the getHints.php script which returns either "no suggestion" or a comma separated list of names matching the input string (in the GET parameter "q") is provided below:
    
    <?php
    // Array with names
    $allnames ="JOSE
    TRISTAN
    NICK
    CHRISTIAN
    COREY
    JOHN
    JACK
    PAUL
    PAUL
    SONNY
    ALEX
    COURTNEY
    HANS
    ETHAN
    TOM
    CORNEL
    BEN
    JOSHUA
    KHADIJAH
    CAMERON
    ABYGAYLE
    ADAM
    SAM 
    RYAN
    ";
    
    $names = explode("\n",$allnames);
    // get the q parameter from URL
    $q = $_GET["q"];
    
    $hint = "";
    
    // lookup all hints from array if $q is different from ""
    if ($q != "") {
      foreach($names as $name) {
        if (preg_match("/^{$q}/i", $name)) {
          if ($hint == "") {
            $hint = $name;
          } else {
            $hint .= ", $name";
          }
        }
      }
    }
    
    // Output "no suggestion" if no hint was found or output correct values, separated by comma
    echo $hint == "" ? "no suggestion" : $hint;
    ?>
            
    • Createa a new getNames.php script to have
      
       $allnames=
      "21211,John,Smith
      2133,Jane,Doe
      5331,John,Doe";
            
      and to return all information as a JSON encoded array (use json_encode()).
    • Modify your getHint JS function to call the getNames script and display the result as a JSON string in the txtHint field