JavaScript: JSON

Learn the JSON data format, how to convert between JSON and JavaScript objects, and how to use JSON with APIs and localStorage.

What is JSON?

JSON (JavaScript Object Notation) is a lightweight, text-based data format used to exchange data between a client and a server. It is language-independent but uses JavaScript-like syntax, making it the universal format for REST APIs.

JSON

JSON is just text: a string that represents structured data in a standardised format.

  • Used by virtually every REST API to send and receive data
  • Human-readable and easy to write by hand
  • Supported natively in JavaScript with JSON.parse() and JSON.stringify()
  • A JSON file typically has the .json extension and application/json MIME type

JSON is Text

JSON travels as a string and must be parsed before you can work with it as an object.

JSON Syntax Rules

JSON has stricter syntax than JavaScript objects. A single mistake: like a trailing comma or a single-quoted key, makes the entire string invalid.

JSON Syntax Rules

JSON is a strict subset of text: not all valid JavaScript objects are valid JSON.

  • Keys MUST be double-quoted strings: "name", not name or 'name'
  • String values MUST use double quotes: "Alice", not 'Alice'
  • Valid value types: string, number, boolean, null, array, object
  • No trailing commas after the last property or array element
  • No functions, undefined, Date objects, or comments allowed

Valid vs Invalid JSON

Keys and string values must use double quotes: no trailing commas, no functions.

JSON.stringify()

JSON.stringify() converts a JavaScript value into a JSON string. Use it before sending data to a server or saving to localStorage.

JSON.stringify(value, replacer, space)

stringify turns any serialisable JS value into a JSON string ready for storage or transmission.

  • First arg: the value to serialise
  • Second arg (replacer): an array of keys to include, or a function to transform values: pass null to include all
  • Third arg (space): number of spaces (or a string) for pretty indentation
  • undefined, functions, and Symbols are silently omitted from the output

JSON.stringify() Options

Use the replacer and space arguments to filter keys or format output for readability.

JSON.parse()

JSON.parse() converts a JSON string back into a JavaScript value. It throws a SyntaxError if the string is not valid JSON.

JSON.parse(text, reviver)

Always wrap JSON.parse() in try...catch when parsing untrusted or user-supplied strings.

  • Returns the parsed value: object, array, string, number, boolean, or null
  • Throws SyntaxError on invalid JSON: catch it to handle bad input gracefully
  • Optional second arg (reviver): a function called on each key/value pair to transform values
  • Commonly used to restore Date objects: parse ISO string back into a Date with a reviver

JSON.parse() with Error Handling

Wrap parse in try...catch so invalid input does not crash your app.

Working with JSON Data

Once parsed, JSON data is a regular JavaScript object or array. You access, map, filter, and modify it using all the standard JavaScript techniques.

Using Parsed JSON

After JSON.parse(), treat the result exactly like any other JS object or array.

  • Access properties with dot or bracket notation: data.user.name
  • Iterate arrays with forEach, map, filter
  • Modify a copy and re-stringify with JSON.stringify() to send updates back
  • Use optional chaining (?.) to safely navigate deeply nested properties

Filtering Parsed JSON

Parse once, then use any JS array method to work with the data.

JSON in localStorage

localStorage only stores strings. Use JSON.stringify() to save objects and JSON.parse() to read them back.

Persisting Objects in localStorage

Without stringify, localStorage stores '[object Object]': always serialise first.

  • Save: localStorage.setItem("key", JSON.stringify(value))
  • Load: JSON.parse(localStorage.getItem("key"))
  • getItem returns null if the key does not exist: handle that case before parsing
  • localStorage is synchronous and limited to ~5MB: not suitable for large datasets

localStorage with JSON

Stringify before saving, parse after loading: guard against null when the key is missing.

Sending and Receiving JSON via Fetch

When working with REST APIs you stringify the request body and parse the response body. The Content-Type header tells the server what format you are sending.

JSON with Fetch

Stringify the body on the way out, call res.json() on the way in.

  • Sending: body: JSON.stringify(data) with Content-Type: application/json
  • Receiving: const data = await res.json() parses the response body automatically
  • Always check res.ok before calling res.json(): a 404 body may not be valid JSON
  • Set Accept: application/json to tell the server you expect JSON back

POST JSON via Fetch

Stringify the payload for the request body and parse the JSON response automatically.

Handling Nested JSON

Real-world API responses are often deeply nested objects. Use optional chaining and destructuring to navigate them safely without crashing on missing properties.

Nested JSON

Optional chaining (?.) short-circuits to undefined instead of throwing when a property is missing.

  • Dot notation: data.user.address.city: throws if any step is null/undefined
  • Optional chaining: data.user?.address?.city: returns undefined safely
  • Nullish coalescing: data.user?.age ?? "unknown": provides a fallback
  • Destructuring with defaults: const { name = "Guest" } = data.user ?? {}

Navigating Nested JSON

Optional chaining and nullish coalescing prevent crashes on missing fields.

JSON Validation

Validating JSON means two things: checking that the string is syntactically valid JSON, and checking that the parsed data has the expected shape (required fields, correct types).

JSON Validation

Syntax validity and schema validity are separate concerns: handle both for robust code.

  • Syntax check: wrap JSON.parse() in try...catch: if it throws, the string is invalid
  • Shape check: after parsing, verify required fields exist and have the expected types
  • For production apps, use a schema library like Zod or Joi for thorough validation
  • Always validate JSON coming from external sources: never trust user or API input blindly

JSON Validation Pattern

Check syntax with try...catch, then validate the shape manually before using the data.

Knowledge Check

1. What does JSON stand for?

2. Which of these is valid JSON?

3. What does JSON.stringify() do?

4. What does JSON.parse() return when given '{"score":100}'?

5. What happens if you call JSON.parse() on an invalid JSON string?

6. How do you store an object in localStorage?

7. What is the third argument of JSON.stringify() used for?