facebook google plus twitter
Webucator's Free Advanced JavaScript Programming Tutorial

Lesson: JSON

Welcome to our free Advanced JavaScript Programming tutorial. This tutorial is based on Webucator's Advanced JavaScript Programming course.

JSON, or JavaScript Object Notation, is a data-interchange format commonly used in JavaScript.

Lesson Goals

  • Learn how to use array and object literals
  • Learn what JSON is and how to use it for data transfer in JavaScript

JSON

JSON is a lightweight format for exchanging data between the client and server. It is often used in Ajax applications because of its simplicity and because its format is based on JavaScript object literals. We will start by reviewing JavaScript's object-literal syntax and then we will see how we can use JSON in an Ajax application.

Review of Object Literals

Arrays

Array literals are created with square brackets as shown below:

var beatles = ["Paul","John","George","Ringo"];

This is the equivalent of:

var beatles = new Array("Paul","John","George","Ringo");

Objects

Object literals are created with curly brackets:

var beatles = {
"Country" : "England",
"YearFormed" : 1959,
"Style" : "Rock'n'Roll"
}

This is the equivalent of:

var beatles = new Object();
beatles.Country = "England";
beatles.YearFormed = 1959;
beatles.Style = "Rock'n'Roll";

Just as with all objects in JavaScript, the properties can be references using dot notation or bracket notation.

alert(beatles.Style); //Dot Notation
alert(beatles["Style"]); //Bracket Notation

Arrays in Objects

Object literals can contain array literals:

var beatles = {
"Country" : "England",
"YearFormed" : 1959,
"Style" : "Rock'n'Roll",
"Members" : ["Paul","John","George","Ringo"]
}

Objects in Arrays

Array literals can contain object literals:

var rockbands = [
{
"Name" : "Beatles",
"Country" : "England",
"YearFormed" : 1959,
"Style" : "Rock'n'Roll",
"Members" : ["Paul","John","George","Ringo"]
},
{
"Name" : "Rolling Stones",
"Country" : "England",
"YearFormed" : 1962,
"Style" : "Rock'n'Roll",
"Members" : ["Mick","Keith","Charlie","Bill"]
}
]

Back to JSON

On the JSON website (http://www.json.org), JSON is described as:

  1. "a lightweight data-interchange format"
  2. "easy for humans to read and write"
  3. "easy for machines to parse and generate"

Numbers 1 and 3 are certainly true. Number 2 depends on the type of human. Experienced programmers will find that they can get comfortable with the syntax relatively quickly.

JSON Syntax

The JSON syntax is like JavaScript's object literal syntax except that the objects cannot be assigned to a variable. JSON just represents the data itself. So, the Beatles object we saw earlier would be defined as follows:

{
"Name" : "Beatles",
"Country" : "England",
"YearFormed" : 1959,
"Style" : "Rock'n'Roll",
"Members" : ["Paul","John","George","Ringo"]
}

JSON Parsers

As JSON is just a string of text and not an object in and of itself, it needs to be converted to an object to make it useful. Although this can be done in JavaScript with the eval() function, it is safer to use a JSON parser. You can download the JavaScript JSON parser at http://www.json.org/json.js. Including this file on a web page allows you to take advantage of the JSON object, which has the following very useful methods:

  • JSON.parse(strJSON) - converts a JSON string into a JavaScript object.
  • JSON.stringify(objJSON) - converts a JavaScript object into a JSON string.

The process for sending data between the browser and server with JSON is as follows:

  1. On the client-side:
    • Create a JavaScript object using the standard or literal syntax.
    • Use the JSON parser to stringify the object.
    • Send the URL-encoded JSON string to the server as part of the HTTP Request. This can be done using the HEAD, GET or POST method by assigning the JSON string to a variable. It can also be sent as raw text using the POST method, but this may create extra work for you on the server-side.
  2. On the server-side:
    • Convert the incoming JSON string to an object using a JSON parser for the language of your choice. At http://www.json.org, you'll find JSON parsers for many modern programming languages. The methods available depend upon which parser you are using. See the parser's documentation for details.
    • Do whatever you wish with the object.
    • If you wish to send JSON back to the client:
      • Create a new object for storing the response data.
      • Convert the new object to a string using your JSON parser.
      • Send the JSON string back to the client as the response body (e.g, Response.Write(strJSON), echo $strJSON, out.write(strJSON) etc.).
  3. On the client-side:
    • Convert the incoming JSON string to an object using the JavaScript JSON parser.
    • Do whatever you wish with the object.
    • And so on...

The examples below show how to transfer data to the server using JSON.

Code Sample:

JSON/Demos/SendJson.html
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="json.js"></script>
<script type="text/javascript">
	function sendRequest(msg) {
		document.getElementById("ResponseDiv").innerHTML = "";
		var objJSON = {
			"msg": msg
		};
		var strJSON = encodeURIComponent(JSON.stringify(objJSON));
		var xmlhttp = new XMLHttpRequest();
		xmlhttp.open("post", "ReceiveJSON", true);

		xmlhttp.onreadystatechange = function() {
			respond(xmlhttp);
		}

		xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
		xmlhttp.send("strJSON=" + strJSON);
	}

	function respond(xmlhttp) {
		document.getElementById("ResponseDiv").innerHTML = xmlhttp.responseText;
	}

	window.onload = function() {
		var btnHi = document.getElementById("hi");
		var btnBye = document.getElementById("bye");
		btnHi.addEventListener('click', function() {
			sendRequest(btnHi.innerHTML);
		}, false);
		btnBye.addEventListener('click', function() {
			sendRequest(btnBye.innerHTML);
		}, false);
	};
</script>
<title>Using JSON</title>
</head>

<body>
<h1>Request</h1>
<button id="hi">Hi There!</button>
<button id="bye">Good bye!</button>
<h1>Response</h1>
<div id="ResponseDiv">Waiting...</div>
</body>
</html>

Code Explanation

To run this demo, load and start the Node.js server as before:

  • Navigate to JSON/Demos from the command line
  • Type npm install to load the needed modules
  • Type npm start to start the server
  • View the page via the URL http://localhost:8080/SendJson.html

The server-side end of this process is the ReceiveJSON response route in server.js. In response to a POST request, it responds with either "And hi there to you!" (if the request parameter strJSON's msg field has value "Hi There!") or "Later Gator!" (if the msg field has any other value).

This code is relatively simple. The client-side script:

  • creates a simple JSON object with one property holding the passed in MSG string.
  • converts the JSON object to a string and encodes it.
  • passes the string as a parameter of our Ajax request.
  • outputs the responseText to the page.

The server-side script:

  • decodes the passed in string and converts it to a JSON object.
  • outputs an appropriate response.

Using JSON

Duration: 30 to 40 minutes.

In this exercise, you will create an Ajax Quiz that uses JSON to pass data to the server.

  1. From the command line, navigate to the directory JSON/Exercises/ and type npm start to start the Node.js server.
  2. Open JSON/Exercises/AjaxQuiz.html in your editor.
  3. Review the HTML. Notice the questions are named "q1", "q2", and "q3" and that each question has an associated result div.
  4. When the page loads, we call the init() function, which attaches the checkAnswer() function to click events of all the input elements in the form.
  5. Write the checkAnswer() function. It should do the following:
    1. Create an object with two properties: question and answer, that hold the question number (e.g, "q3") and the user's answer (e.g, "3").
    2. Pass that object to the JSON parser to stringify. That should result in a string like: {"question" : "q3","answer" : "3"}
    3. Encode that, and store it in a new object as the strJSON property.
    4. Write out "checking..." to the appropriate result div while awaiting a response from the server.
    5. Using Ajax, send the data to the server to be processed by /AjaxQuiz, which expects a strJSON parameter to be posted.
    6. The callback function is respond() and expects two parameters: the XMLHttpRequest object and the result div.
  6. Write the respond() function so that it outputs the server response text to the appropriate result div.
  7. Test your solution in a browser by visiting http://localhost:8080/AjaxQuiz.html.

Challenge

Modify the quiz so that all questions are processed at once:

  1. Save AjaxQuiz.html as AjaxQuiz-challenge.html. Add a button at the bottom of the HTML form that, when clicked, calls checkQuiz() and passes it the form object.
  2. The checkQuiz() function should create a string with the following format:
    { "answers" : [a1, a2, a3] }
    where a1, a2, and a3 hold the user's answers, or "x" if the question is not answered. For example, if the user answers 3 for the first question, 2 for the second question, and leaves the third question unanswered, the JSON string should look like this: { "answers" : ["1", "3", "x"] }. The function should then pass that string to the /AjaxQuiz-challenge Node.js response route, which is already written.
  3. The server-side script will return a JSON string with the following format:
    {"q1":"Wrong","q2":"Right","q3":"Unanswered"}
  4. Based on the string the server returns, write out the server responses (e.g, "Wrong") to the q1Result, q2Result, and q3Result divs.

Solution:

JSON/Solutions/AjaxQuiz.html
---- C O D E   O M I T T E D ----

	function respond(xmlhttp, resultDiv) {
		resultDiv.innerHTML = xmlhttp.responseText;
	}

	function checkAnswer(e) {
		var target = e.target;
		var q = target.name;
		var a = target.value;
		var objQuestion = {
			question: q,
			answer: a
		};
		var resultDiv = document.getElementById(q + "Result");
		var strJSON = encodeURIComponent(JSON.stringify(objQuestion));
		resultDiv.innerHTML = "checking...";
		var xmlhttp = new XMLHttpRequest();
		xmlhttp.open("post", "AjaxQuiz", true);
		xmlhttp.onreadystatechange = function() {
			if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
				respond(xmlhttp, resultDiv);
			}
		}
		xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
		xmlhttp.send("strJSON=" + strJSON);
	}

	window.onload = function() {
		init();
	}
</script>
---- C O D E   O M I T T E D ----

Code Explanation

Challenge Solution:

JSON/Solutions/AjaxQuiz-challenge.html
---- C O D E   O M I T T E D ----

	function init() {
		var quiz=document.getElementById("quizForm");
		var sbtButton = document.getElementById("sbtButton");
		sbtButton.addEventListener('click', function() {
				checkQuiz(quiz);
			},
			false);
	}
	
	function respond(xmlhttp) {
		var strJSON = decodeURIComponent(xmlhttp.responseText);
		var objJSON = JSON.parse(strJSON);
		for (i in objJSON) {
			document.getElementById(i + "Result").innerHTML = objJSON[i];
		}
	}
	
	function checkQuiz(form) {
		var a1 = getAnswer(form.q1);
		var a2 = getAnswer(form.q2);
		var a3 = getAnswer(form.q3);
		var objJSON = {
			"answers" : [a1, a2, a3]
		}
		var strJSON = JSON.stringify(objJSON);
		var xmlhttp = new XMLHttpRequest();
		xmlhttp.open("post","AjaxQuiz-challenge",true);
		xmlhttp.onreadystatechange = function() {
			if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
				respond(xmlhttp);
			}
		}
		xmlhttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=UTF-8");
		xmlhttp.send("strJSON=" + encodeURIComponent(strJSON));
	}
	
	function getAnswer(radio) {
		for (var i=0; i<radio.length; i++) {
			if (radio[i].checked) {
				return radio[i].value;
			}
		}
		return null;
	}
	
	window.onload = function() {
		init();
	}
</script>
---- C O D E   O M I T T E D ----

<input type="button" id="sbtButton" name="Submit" value="Check Answers">
</form>
</body>
</html>

Code Explanation