Topic 04

JSON

JavaScriptConcept

An object lives in the memory of one open page, and it disappears when the page closes. The moment data has to travel, from a server to a browser, into a file, or into the browser's own storage, it has to become text, because text is what files and networks carry. JSON, short for JavaScript Object Notation and usually said like the name Jason, is the text format almost everyone uses for that. It looks so much like a JavaScript object that the difference is hard to see, and it is important to know.

A flat-packed wardrobe shows the difference. Flat, it travels in a box and fits through any door, but you cannot hang a coat in it. Assembled, it is useful, but it does not travel. JSON is the flat pack; turning it into an object is the assembly, and turning an object back into JSON is packing it flat again.

Text That Looks Like an Object

Here are the site's three projects written as JSON, the way they will sit in a file of their own in Chapter 11. The shape is the same as the array from topic 2: square brackets around the list, curly braces around each project. Two things differ. Every key is in double quotes, and there is no const projects at the start, because JSON is only the data, never the code that uses it.

Fragment: JSON text
[
  {
    "title": "Budget Tracker",
    "description": "Adds up a month of spending from a spreadsheet.",
    "tags": ["javascript"],
    "url": "https://example.com/budget"
  },
  {
    "title": "Recipe Cards",
    "description": "A responsive page of recipes that prints cleanly.",
    "tags": ["html", "css"],
    "url": "https://example.com/recipes"
  },
  {
    "title": "Weather Now",
    "description": "Shows today's forecast for any city.",
    "tags": ["javascript", "api"],
    "url": "https://example.com/weather"
  }
]

The important difference is invisible. When this arrives from a server or is read from a file, it is not an array at all: it is one long string that happens to contain brackets and quotes. Until it is turned into a real value, your code cannot reach the second project or its title. Index 0 of that string is not the first project; it is the opening square bracket, a single character.

The Rules of JSON

JSON is stricter than JavaScript, and its rules are short. Every key must be in double quotes, and so must every string; single quotes cannot take their place. An apostrophe inside a string, as in today's, is fine. There is no comma after the last item of a list or the last property of an object. There are no comments.

The values JSON can hold are strings, numbers, true, false, null, arrays and objects, and nothing else. A function cannot be written in JSON, and neither can undefined. Because the format is this small, almost every programming language can read and write it, which is why a server written in any language can send JSON to your page.

JSON.parse and JSON.stringify

Two built-in functions move data across the line between text and values. JSON.parse takes JSON text and returns the value it describes: an array, an object, a number. The Console below parses a short piece of JSON and then reads from the result.

Console
> const text = '[{"title": "Budget Tracker", "tags": ["javascript"]}]';
undefined
> typeof text
'string'
> const data = JSON.parse(text);
undefined
> data[0].title
'Budget Tracker'
> data[0].tags.length
1

The text is written in single quotes here, because it is full of double quotes itself; JavaScript accepts either kind around a string. Asking typeof confirms it is a string. After JSON.parse, the name data points at a real array holding one real object, so the usual reading works: its first item's title is Budget Tracker, and it has one tag.

JSON.stringify goes the other way: it takes a value and returns JSON text. Given a third argument, a number of spaces, it lays the text out on several lines with that much indentation, which makes it much more readable. The second argument is a slot for an option this book does not use, so it is always null here.

Console
> const card = { title: "Recipe Cards", tags: ["html", "css"], featured: undefined };
undefined
> JSON.stringify(card)
'{"title":"Recipe Cards","tags":["html","css"]}'
> console.log(JSON.stringify(card, null, 2));
{
  "title": "Recipe Cards",
  "tags": [
    "html",
    "css"
  ]
}
undefined

The first result is the whole object squeezed onto one line of text, with double quotes around every key. The second, logged with an indent of two spaces, puts each property on its own line. In both, the property called featured has vanished, because its value was undefined and JSON has no way to write that. A property whose value is a function is dropped in the same way, without any warning.

When JSON Is Broken

A mistake in JSON text makes JSON.parse stop with a SyntaxError, the same kind of error Chapter 6 showed for broken JavaScript: the text cannot be read. A very common mistake is a comma after the last item, which JavaScript allows and JSON does not.

Console
> JSON.parse('["html", "css",]')
Uncaught SyntaxError: Unexpected token ']', "["html", "css",]" is not valid JSON

Read aloud, the message says: syntax error, unexpected token, the closing square bracket, and the text is not valid JSON. A token is one piece of the text, such as a bracket, a comma or a string. After a comma, JSON expects another value, and a closing bracket is not one. Delete the comma and the same line returns an array of two tags. When you write a JSON file by hand, check for three things before anything else: a trailing comma, a single quote, and a comment.

Where JSON Appears in This Book

From here on, JSON turns up wherever data leaves the page or arrives at it. In Chapter 9, the browser's storage keeps only strings, so anything more than a word goes in with JSON.stringify and comes out with JSON.parse. In Chapter 11, the projects move into a file called data/projects.json, exactly the text at the top of this page, and the page loads and parses it. Later in that chapter, a live service answers with JSON too, and the Network panel in DevTools shows each answer laid out so you can read it.

Two forms of the same data
JSON text
Travels and is stored. Your code cannot read a title out of it yet.
parse and stringify
JSON.parse: text to value. JSON.stringify: value back to text.
Object or array
Used by your code: loop over it, filter it, read its keys.
Common Confusions
  • "JSON and JavaScript objects are the same thing." JSON is text with stricter rules; an object is a live value. One becomes the other only through JSON.parse and JSON.stringify.
  • "Single quotes are fine in JSON." Only double quotes are valid, around keys and strings alike. Single quotes make JSON.parse fail.
  • "JSON.stringify keeps everything." Properties whose values are functions or undefined are left out, silently.
Why It Matters
  • Every piece of data the site loads or stores later in the book passes through these two functions.
  • Knowing the rules means a JSON file you write by hand works the first time, instead of failing with an error about an unexpected token.

Knowledge Check

Which of these is valid JSON?

  • {'title': 'Recipe Cards'}
  • {"title": "Recipe Cards",}
  • {"title": "Recipe Cards"}
  • {title: "Recipe Cards"}

What does JSON.parse return when given valid JSON text?

  • The same text, laid out on several lines
  • The array or object that the text describes
  • true if the text is valid, false if it is not
  • A file saved on disk that contains the data

What happens to { a: 1, b: undefined } when it goes through JSON.stringify?

  • Both properties are kept, with b as undefined
  • It throws a SyntaxError about the undefined value
  • Property b is kept, but its value becomes null
  • Property b is dropped, leaving only a with 1

Data has just arrived from a server as JSON. What is it, before your code does anything?

  • A string of text that still needs parsing
  • An array that the code can loop over
  • A function that builds the data when run
  • A set of elements already on the page

You got correct