jsonjavascriptapifetchtutorial

JSON in JavaScript: parse, stringify, fetch and localStorage

·9 min read

Working with JSON in JavaScript

JSON is JavaScript's native data format. Every modern browser has JSON.parse() and JSON.stringify() built in, and the fetch API returns JSON by default. Mastering these four patterns covers 90 percent of real-world JSON work in JavaScript.

JSON.parse() — String to Object

JSON.parse() takes a JSON string and returns a JavaScript value — object, array, number, string, boolean, or null.

javascript
const json = '{"name": "Ravi", "age": 28, "active": true}';
const obj  = JSON.parse(json);

console.log(obj.name);   // "Ravi"
console.log(obj.age);    // 28
console.log(obj.active); // true

Always wrap JSON.parse() in try/catch. Invalid JSON throws a SyntaxError that will crash your application if unhandled:

javascript
function safeParseJSON(str) {
  try {
    return { data: JSON.parse(str), error: null };
  } catch (e) {
    return { data: null, error: e.message };
  }
}

const { data, error } = safeParseJSON(rawString);
if (error) console.error("Parse failed:", error);

JSON.stringify() — Object to String

JSON.stringify() converts a JavaScript value to a JSON string.

javascript
const user = { name: "Ravi", age: 28, city: "Surat" };
const json = JSON.stringify(user);
// '{"name":"Ravi","age":28,"city":"Surat"}'

Add the third argument for pretty-printing with indentation:

javascript
const pretty = JSON.stringify(user, null, 2);
// {
//   "name": "Ravi",
//   "age": 28,
//   "city": "Surat"
// }

What JSON.stringify() Silently Drops

These JavaScript values are not part of JSON and are handled automatically — sometimes in surprising ways:

javascript
const obj = {
  a: 1,
  b: undefined,        // dropped entirely
  c: function() {},    // dropped entirely
  d: Symbol("x"),      // dropped entirely
  e: NaN,              // becomes null
  f: Infinity,         // becomes null
};

JSON.stringify(obj);
// '{"a":1,"e":null,"f":null}'

If you need to preserve undefined values, convert them to null before stringifying.

The replacer Argument — Filter or Transform Keys

Pass an array of key names to include only those keys in the output:

javascript
const user = { id: 1, name: "Ravi", password: "secret", role: "admin" };
JSON.stringify(user, ["id", "name", "role"]);
// '{"id":1,"name":"Ravi","role":"admin"}'

Pass a function for custom control over each value:

javascript
JSON.stringify(user, (key, value) => {
  if (key === "password") return undefined; // exclude
  if (typeof value === "string") return value.trim(); // transform
  return value;
});

The reviver Argument — Transform While Parsing

The reviver function in JSON.parse() runs on every key-value pair while the JSON is being parsed. This is the correct way to restore Date objects:

javascript
const json = '{"name":"Ravi","createdAt":"2025-01-15T10:30:00Z"}';

const obj = JSON.parse(json, (key, value) => {
  if (key === "createdAt") return new Date(value);
  return value;
});

console.log(obj.createdAt instanceof Date); // true
console.log(obj.createdAt.getFullYear());   // 2025

Fetch API with JSON — GET Request

The fetch API has a built-in .json() method that calls JSON.parse() for you:

javascript
async function getUser(id) {
  const response = await fetch(`https://api.example.com/users/${id}`);

  if (!response.ok) {
    throw new Error(`HTTP ${response.status}: ${response.statusText}`);
  }

  return response.json(); // parses JSON automatically
}

const user = await getUser(1);
console.log(user.name);

Always check response.ok before calling .json(). A 404 or 500 response has a body too — it is just an error body.

Fetch API with JSON — POST Request

When sending JSON in a POST request, set the Content-Type header and stringify the body:

javascript
async function createUser(userData) {
  const response = await fetch("https://api.example.com/users", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "Authorization": "Bearer " + getToken(),
    },
    body: JSON.stringify(userData),
  });

  if (!response.ok) {
    const err = await response.json();
    throw new Error(err.message ?? "Request failed");
  }

  return response.json();
}

const newUser = await createUser({ name: "Ravi", email: "ravi@example.com" });

Without Content-Type: application/json, the server may not parse the request body correctly.

localStorage with JSON

localStorage only stores strings. Serialize with JSON.stringify when saving and parse with JSON.parse when loading:

javascript
// Save an object
const settings = { theme: "dark", fontSize: 14, lang: "en" };
localStorage.setItem("settings", JSON.stringify(settings));

// Load it back
const raw     = localStorage.getItem("settings");
const settings = raw ? JSON.parse(raw) : { theme: "light", fontSize: 14, lang: "en" };

Always provide a fallback value — the key may not exist if the user has never saved settings.

Deep Clone with JSON

A quick way to deep-clone a plain object is to stringify then parse it:

javascript
const original = { user: { name: "Ravi", tags: ["a", "b"] } };
const clone    = JSON.parse(JSON.stringify(original));

clone.user.name = "Priya";
console.log(original.user.name); // "Ravi" — not affected

Limitation: this only works for values that survive JSON serialization — strings, numbers, booleans, null, plain objects, and arrays. It does not work with Date, Map, Set, Functions, or undefined. For those, use structuredClone() (available in all modern browsers and Node.js 17+).

Handling Dates in JSON

JSON has no Date type. Dates are serialised as ISO 8601 strings. Always store and transmit dates in this format:

javascript
// Serialise
const event = { title: "Launch", date: new Date().toISOString() };
const json  = JSON.stringify(event);
// '{"title":"Launch","date":"2025-05-01T10:30:00.000Z"}'

// Deserialise
const parsed = JSON.parse(json);
const date   = new Date(parsed.date); // restore as Date object
console.log(date.getFullYear()); // 2025

Format JSON for Debugging

You do not always want to minify JSON when logging. Use JSON.stringify with indent=2 to get readable debug output:

javascript
console.log(JSON.stringify(apiResponse, null, 2));

Or paste the response into JSONKit's formatter at /json-formatter for interactive exploration with collapsible tree view and syntax highlighting.

Try JSON Formatter

Format and inspect JSON while working with JavaScript objects.