An introduction to JSON - ENTERING THE THIRD REALM - JavaScript in Plain Language (2015)

JavaScript in Plain Language (2015)

PART IV: ENTERING THE THIRD REALM

4.2 An introduction to JSON

JavaScript Object Notation, JSON (it is pronounced J SON), is an open standard format that uses human-readable text to transmit data objects consisting of key-value pairs (JavaScript objects). It has become an alternate technology to XML in its use for transmitting data between a server and web application. The term ‘alternate’ may be outdated because nowadays JSON is the preferred method for web services.

The reason why I am introducing JSON at this point is because at the time of this writing JSON has become the must know subset of JavaScript if one wants to build modern web pages and web apps. It should be now part the any web literacy curriculum.

JSON has achieved such popularity that other languages are now implementing it in their own vocabulary.

The good news is that you have already been prepared for this technology throughout the book and it is just a matter of becoming more aware of its existence.

JSON format is syntactically the same as when we create lists, being it numeric as an array or with key-value pairs as in an object. We can also combine the two formats to create a more complex JSON data structure.

The following is a collection of data written in the JSON format:

{
"firstName": "Tony",
"lastName": "deAraujo",
"age": 99
}

Or we can also have an array:

[1, "hello", 33]

Please note: If you are planning to convert an array into a JSON format, avoid using mixed array data types like the array I’ve just shown you. This is because JSON is supposed to be a language neutral data exchange protocol and many programming language do not allow mixed arrays (those containing mixed value types) and this would cause confusion. The following would be ok because numbers are seen as strings (compare with my previous example):

["1", "hello", "33"]

Going back to our first example on the top, notice how there is no variable assignment to the JSON object or array. The JSON part of the object is the one that gets exported into other systems in a seamless manner.

When writing in JSON format we must wrap the key in double quotes. Since we have used double quotes from the very beginning we should have no problems with that.

JSON will throw an error if keys are not wrapped in double quotes. Single quotes will not work.

Also none of these data structures terminate with a semicolon. This is not a variable assignment. JSON data is assigned to a variable at its destination so that we can manipulate the data, but the data in itself is exported without variables. The outer most tags wrapping the whole data structuremust be curly braces, like in an object format.

In a more complex design you may see an array of objects. Arrays work out great to gather a bunch of objects that belong to a certain class criteria:

Fig 18 (note: missing outer curly braces and a key for the array. See explanation below.)

This is the data that can be portable from machine to machine. However, this is not yet a valid JSON object and using it like this can lead to an unsecure transmission. It needs outer curly braces and a key name for the array in order to become a good JSON data format as we will see on the next image.

By writing it this way (plus the outer curly braces) we can feed it into any machine able to translate JSON data into their own machine format, much like XML doe except that JSON is easier to implement.

For a while now, web pages have been communicating with the server by exchanging JSON data. What I mean is that the page loads on your browser and every time you click on a dynamic field, the page remains the same but the data is updated via a JSON data format exchange. This is one of the reasons why becoming aware of this technology is a must.

· Keep this in mind: JSON-formatted text is also syntactically legal JavaScript code. However, the opposite or other way around may not be true. This is the reason why, when we learned to create objects earlier, I chose to wrap the keys in double quotes, making it legal syntax for both JavaScript and JSON.

The next image will show a more extensive example of a JSON object. You will see the outer object subdivided into two key names: staff and management.

Each one of these keys, staff/management, will have an array as a value. The arrays will contain several individual records in the form of objects. Each object represents an employee from either staff or management. Let’s look at the image:

Fig 19 see raw file | bit.ly/1uF1qNH

Do you see how that is done? There are two properties: staff and management.

In our example, the property staff contains an array of people assigned to it, and each person is also an object with its own data. Right now we only have "Tony" as staff and we only have "Judy" as management, but we could add a comma after the closing brace from "Tony" or from "Judy", and add another person to each array, as you will see on the picture further down the page.

Don’t get confused here. Arrays are not necessary in order to create JSON data structures. We can have arrays, strings, numbers and objects, represented in a JSON structure. Every identifier needs to be wrapped in double quotes, except for numbers in which quotes are optional. (As noted earlier, always double quote numbers if they are contained in an array, in order to comply with programming languages that forbid mixed arrays).

Use jsonlint, a tool to check JSON validation

In order to see if a code block is syntactically well written in JSON we can check it with an online tool called jsonlint (jsonlint.com). This tool becomes an important check in order to avoid errors or unsecured JSON data scripts.

Practicing exercise:

1- Copy the code from the previous image and paste it on the box at jsonlint. Then click validate. If everything is well written, you should see a green bar across the page.

2- Try removing a brace, or adding a variable name, or a semicolon just to see if it still validates.

Assigning a JSON object to a variable

Now, if we want to manipulate this data after we receive it at the destination, we need to assign it to a variable. The variable will point to the data in memory so that we can address it. That’s when JavaScript comes in: We move data around in the JSON format, and at the destination we assign the data to a variable if we want to further manipulate the data.

The next extended image will show how we can assign a variable to the JSON object.

Remember, when writing your code, if you want to validate your JSON data with jsonlint, you must do it before assigning the JSON data to a variable and before adding the semicolon at the end to terminate the statement.

Fig 20 see raw file | bit.ly/1DwXd57.

3- On this step extend your own object with more data, or copy it from the raw file below image 20.

If you are writing your own script and want to validate it with jsonlint, do it before adding the variable (ex: var employees = ) and last semicolon, then assign the variable employees to the object.

Now that we have assigned the JSON object to the variable employees, we can edit, add, delete and display the data or part of the data because the object has a name we can refer to.

Editing the JSON object

The property key staff has an array assigned to it. The decision to have an array was so that we could include several objects as part of staff. Each person in the array is an object in itself. The same goes for key management which is also a property of the object employees.

Practicing exercise:

4- If you haven’t done so, copy the raw file and paste it onto your JavaScript Console.

5- How would we address staff in order to get a list of its members?
We could use dot syntax in the following manner:
employees.staff;

That would give us a list of employees from the staff array. Your Console might display a short version of it, something like object, object, object, which represents each employee, but in real life you would get the complete list. To see the contents of each object, just click on it (see the image below). That’s how the Console treats the output.

Fig 21

NOTE: The proto property is a list of all the methods from the JavaScript library that apply to this object. Just ignore it because it has nothing to do with JSON and it is not portable. I cover all these library methods on the Volume 2 book.

6- How would we address the first object in the staff array?
employees.staff[0];

Explanation:
We start with the outer object which is employees, and then address its staff member. Then, since staff holds as array of inner objects, we address the first element of the array which is at location zero, and the result is as follows:

Object {firstName: "Tony", lastName: "deAraujo", age: 99}

7- Now try addressing the object in the array held by staff at the position containing Mary. She is the third element of the staff array, which corresponds to position 2.
See the result here: raw file | bit.ly/1sWuXAy.

8- And how would we add a new employee to the staff class?
This is the new employee we need to add:
"firstName":"Loren", "lastName":"Santos", "age":29

Since Loren is an object that needs to be added to an array, we could use the array method push() to push it into staff: (see raw file | bit.ly/1wKTPPB ).

employees.staff.push({"firstName":"Loren", "lastName":"Santos", "age":29});

9- Try adding a new member to employees management, like for example:
"firstName":"Peter", "lastName":"Jones", "age":55

When finished, try addressing (displaying) this new member at its location in the array assigned to management.

See raw file | bit.ly/1tXHoQM

10- Call the employees property management to see what it contains:

Great! Now let’s just look at two useful methods to work with JSON data structures.

JSON library methods

JavaScript has two functions to parse regular JavaScript into a JSON format, or vice versa. Once data is converted into a JSON format we can send the data across the globe into other machines.

Let’s see how they basically work.

JSON.stringify

The function stringify compresses the object by stripping its white space and converting it into a string so it can be exported.

Taking for example our previous object employees (as seen on image 20), we can strigify it like this:

var myString = JSON.stringify(employees);

I have assigned the result to variable myString (any name will do) which is now a string variable and contains the following data:

"{"staff":[{"firstName":"Tony","lastName":"deAraujo","age":99},{"firstName":"John","lastName":"Smith","age":33},{"firstName":"Mary","lastName":"Adams","age":29}],"management":[{"firstName":"Judy","lastName":"Garland","age":43}]}"

Now this string of data is ready to be sent via http or any other method to a different location or machine. Any programming language with a way to decode JSON (convert to or read to JSON) will be able to use this data.

NOTE(1): If you want to validate this data with JSONLINT.com you need to exclude the variable name and the outer quotes.

NOTE(2): When using stringify, functions (methods) inside of the original object will not be included. This is intentionally done. The only data that gets stringified are the string key/value pairs which are wrapped in quotes (as well as numbers).

NOTE(3): There is a way to prevent JSON from compressing the data. That implementation will be discussed when we cover the third argument for stringify, a few pages from now.

Using a second argument as a filter on stringify

NOTE: If this is too much information for now, just read it, understand it, be aware of it and return when you want to revisit the subject.

The method stringify can take a second argument to filter out everything except what we want to include during stringify. This second argument can be an array, or it can be a function, depending on what we are trying to accomplish.

(a) When using an array as a filter

When we use and array as second argument, we pick and choose the data we want to strigify.

As always, the first argument is the object name being used. When the second argument is an array, JavaScript only strigifies the key/values provided in that array. The array acts as an inclusive filter.

For example, I want to stringify just the array staff and only just the first name of each employee:

var someString = JSON.stringify(employees, ["staff", "firstName"]);

JavaScript captures staff and grabs its firstName property. The result of this serialization is as follows:

"{"staff":[{"firstName":"Tony"},{"firstName":"John"},{"firstName":"Mary"}]}"

Here’s another example where age is also included (but not lastName):

var someString = JSON.stringify(employees, ["staff", "firstName", "age"]);

What if we want the first name of both staff and management?

var someString = JSON.stringify(employees, ["staff", "management", "firstName"]);

It results in:

"{"staff":[{"firstName":"Tony"},{"firstName":"John"},{"firstName":"Mary"}],"management":[{"firstName":"Judy"}]}"

NOTE: If you try validating this result with jsonlint in its raw format, it will fail. The reason is that we need to strip the outer quotation marks (the ones making this whole script a string). Once you remove the outer quotes you will get a green light from jsonlint. There is a method to convert this string back into an object. This method will be discussed on the next chapter.

Try this one on your own:

If you want some practice, try stringifying both staff and management but only the last name and age of each employee. Use a variable name of your choice.

(b) When using a function as a filter

So far we have used an array as a second argument for stringify. That allowed us to pick and choose which elements we wanted to include in the stringification.

With a function as a second parameter we can do the opposite, exclude elements, or modify how certain elements will be represented.

The function takes two arguments in its input parameters. The first argument is the key and the second argument is the value. These two parameters will represent every key and every value of the JSON object. In other words, because we are grabbing each key and each value for evaluation before processing, we can write a script in the body that addresses specific keys and specific values, as the function scans each key and each value (see the image below).

When it comes to parameter names, it doesn’t matter what you call them, what matters is their position which needs to be (key, value). You can call them (k,v) or (x,y), or anything else.

As an example, the following image uses the function filter to exclude the age from the stringification:

Fig 22 see raw file | bit.ly/1v71zuT.

What happens here is that an undefined value will not be included as a JSON file because in JSON, undefined represents and empty key/value pair, so age will be stripped from the output.

As another example, let’s say that you want to show the label age but with a value of n/a. You could change the return value from undefined which strips the key, to the following:
return "n/a";

Now "age" will show "n/a" as a value.

Great!

Moving along, what about programming the opposite, like for example when we receive JSON data and want to reconvert it back into an object?

We will look at the reconversion in a few minutes but let’s first discuss how to prevent stringify() from compressing the data (I mean how to keep the original white space), because it completes our discussion on the function stringify().

Using a third argument on stringify() for controlling white space

Even if we don’t want to use a second argument to filter out the data (like for example an array or a function as explained on the previous page), we could still use a third argument (or parameter) to control the white spacing when we stringify.

Taking for example our original employees object (see raw file | bit.ly/1DwXd57), instead of stringifying it like we did before:

var myString = JSON.stringify(employees);

We could instead, add a third argument, which would activate the third input parameter of function stringify:

var myString = JSON.stringify(employees, null, 4);

And the output would look like in this raw file | bit.ly/1oh4ts1.

First, notice how we made JavaScript read the third argument without having a second argument:

· We made the second argument null. That works because now we can have a third argument.

Second, the number 4 is the number of indented spaces. There is no provision for adding lines but JavaScript automatically adds lines when we ask for indentation. The maximum number is 10.

Did you notice the second sample on the raw file? It shows dots instead of spaces.

That was done by substituting the third argument from a number to a string:

var myString = JSON.stringify(employees, null, "...");

This last one will not validate if you test it on jsonlint, but it serves to illustrate the third argument in stringify.

JSON.parse

To convert the string back into an object just like we had it before, we use the method JSON.parse.

See raw file: myString | bit.ly/1rtZclU.

var myEmployees = JSON.parse(myString);

Variable myEmployees is now an object with the same values as our original employees object.

Note: You will get an error if the data being parsed is not a valid JSON.

Properties of non-array objects are not guaranteed to be stringified in any particular order (which makes sense since key-value pairs don’t really need a numeric order). Do not rely on ordering of properties within the same object when stringifying.

In summary

I hope this introduction to JSON has given you the taste for it and inspire you to start your own data import export projects.

Here are a few useful links:

· JSON.org, the official website.

· JSONLint, the JSON validator tool.

· Wikipedia, an independent reference of resources.

· Mozila Foundation, a good glossary and resource center.

· JSON vs XML – A comparison of these two technologies written by JSON.org.

Before we move on, let me just include a brief introduction of another technology where JSON really shines: NoSQL.

Document-oriented databases for JSON data

Modern web applications have data needs that relational databases like MySQL may have trouble delivering. A massive change is underway and is disrupting the database world as we know it. Today, three interrelated trends are Big Data, Big Users, and Cloud Computing – all pushing the adoption of NoSQL technology.

What is NoSQL?

“A NoSQL or Not Only SQL database provides a mechanism for storage and retrieval of data that is modeled in means other than the tabular relations used in relational databases.”
Wikipedia.

The reason for the term "Not only SQL" database is to emphasize that they may support SQL-like query languages.

NoSQL is increasingly used in real-time web applications (example: Facebook’s news feed and Twitter).

NoSQL are document-oriented databases. Compared to relational databases, a collection of data could be considered analogous to a table and a document analogous to a record (a document could be encapsulated and encoded in one of the standard formats such as XML or JSON).

A list of NoSQL databases can be found here: nosql-database.org.

A good starting point if you want to get into this technology right away is to download CouchDB, which stores data as JSON and it can be queried in JavaScript . You can use it on your local computer and learn its operation from there. CouchDB is an Open Source project supported by Apache. A collection of basic lessons can be found here: Guides.