Skip to main content

JSON File Format

JSON (JavaScript Object Notation) is a modern text format for storing and transmitting structured data in text form. The familiar, object-like JSON syntax is very handy. In this format, data will be received and sent to the server, stored in local storage, etc.

However, JSON is not an object, but its string representation. Below is a sample JSON file. The syntax is similar to objects, except that the keys are always double-quoted strings. String values must also be enclosed in double quotes. Property values can be of the following types: string, number, object, array, boolean and null.

user.json
{
"name": "Josh",
"weight": 175,
"age": 30,
"eyecolor": "brown",
"isHappy": true,
"cars": ["Chevy", "Honda"],
"favoriteBook": {
"title": "The Last Kingdom",
"author": "Bernard Cornwell",
"rating": 8.38
}
}

JavaScript and JSON work great together thanks to the built-in JSON class methods that convert JavaScript objects to JSON, and vice versa. Regardless of what you have, it is easy to get the opposite.

JSON.stringify() method

Receives a value and converts it to JSON. The value can be a number, boolean, null, array or object. Strings are already valid JSON, so converting them is meaningless.

const dog = {
name: "Mango",
age: 3,
isHappy: true,
};

const dogJSON = JSON.stringify(dog);
console.log(dogJSON); // "{"name":"Mango","age":3,"isHappy":true}"

The result of calling JSON.stringify(dog) is valid JSON (string) that can be saved to a file or sent over the Internet.

Not every JavaScript object can be identically converted to JSON. For example, if the object has methods, they will be ignored during conversion.

const dog = {
name: "Mango",
age: 3,
isHappy: true,
bark() {
console.log("Woof!");
},
};

const dogJSON = JSON.stringify(dog);
console.log(dogJSON); // "{"name":"Mango","age":3,"isHappy":true}"

Also, when trying to convert a function to JSON, the result will be undefined.

JSON.stringify(() => console.log("Well, this is awkward")); // undefined

JSON.parse() method

To get a valid JavaScript value from JSON, it must be parsed (parse). This is the inverse operation of converting to a string (stringify). Now that dog is a valid object, you can handle it as usual.

const json = '{"name":"Mango","age":3,"isHappy":true}';

const dog = JSON.parse(json);
console.log(dog); // {name: "Mango", age: 3, isHappy: true}
console.log(dog.name); // "Mango"

Handling errors

If invalid JSON is passed to JSON class methods, they will throw an error, and the whole script will crash. To avoid this, use the try...catch construct, which helps "catch” and handle script execution errors.

try {
// Code that may throw a runtime error
} catch (error) {
// Error handling
}
  1. First, the code inside the try block is executed.
  2. If there are no errors, the catch block is ignored and control is passed on.
  3. If an error occurs in the try block, its execution stops and the interpreter goes to the catch block.

The variable error is an error object with information about what happened. This object has several useful properties:

  • name - type of error. For a parse error, this is SyntaxError.
  • message - message with error details.
  • stack - call stack at the time of error. It is used for debugging.

For example, parsing a string will cause this scenario, because a character string is not valid JSON, since it cannot be converted to a valid JavaScript value.

// Script will crash during parse
const data = JSON.parse("Well, this is awkward");
console.log("❌ You won't see this log");

Using the try...catch construct, you can handle this exception so that the script continues to run even after throwing an error.

try {
const data = JSON.parse("Well, this is awkward");
} catch (error) {
console.log(error.name); // "SyntaxError"
console.log(error.message); // Unexpected token W in JSON at position 0
}

console.log("✅ This is fine, we handled parse error in try...catch");

The same will happen when trying to parse invalid JSON, which, for example, may come from the back-end or be read from a file. In the example, the username property lacks enclosing double quotes.

try {
const data = JSON.parse('{username: "Mango"}');
} catch (error) {
console.log(error.name); // "SyntaxError"
console.log(error.message); // "Unexpected token u in JSON at position 1"
}

console.log("✅ This is fine, we handled parse error in try...catch");

Runtime phases of the code

The code in JavaScript is not executed immediately; first, the engine needs to read the code and find out if it is possible to execute it or not.

Compile or evaluation time is the preparation before code execution, when the engine finds syntax errors, typing errors, etc. It means that the code is not yet executed, but only evaluated. If this phase is successful, it means at least that there are no syntax errors in the code and it can be launched for execution.

Runtime is the phase when the script starts executing. Function call instructions and expression evaluation are executed, the necessary identifiers are searched for in the appropriate scopes, etc.

If this phase is successful, it means that the script is written without any obvious errors and has completed its work. This phase may contain errors related to missing properties and variables, type conversions, etc. That is something that happens only during code execution.

Try to run the following code. Since we made a mistake and instead of const we try to declare the variable value with the keyword cos, ​​a syntax error will be detected at the compilation phase and the runtime phase will not even start. We will immediately see an error message in the console.

console.log('This message will not appear in the console');

cos value = 5;
Interesting that

try...catch handles only errors that occurred during code execution (runtime errors). This means that the code must be syntactically correct, otherwise, the runtime phase will simply not start. Errors occurring during the evaluation phase are called parsing errors.