Parse Nested JSON in JavaScript: Objects, Arrays, and Safe Access

Last updated:

Nested JSON — objects inside objects, or arrays of objects — parses with the same single JSON.parse() call as flat JSON. The challenge is safely reading deep values without triggering TypeError: Cannot read properties of undefined. The 3 safe access patterns are optional chaining (data?.user?.address?.city, ES2020), destructuring with defaults, and explicit null checks at each level. For deeply nested structures (4+ levels), optional chaining is the most readable. In TypeScript, annotate the full nested type to get compile-time path safety. This guide covers all 3 access patterns, nested array handling, and the reviver parameter for transforming values during parse.

Parse nested JSON into a JavaScript object

const raw = '{"user":{"profile":{"name":"Alice","age":31}},"roles":["admin","editor"]}'
const data = JSON.parse(raw)

console.log(data.user.profile.name)
console.log(data.roles[1])

If you need the base parsing pattern first, start with JSON to JavaScript object.

Access deep properties safely

Real payloads often omit optional branches. Optional chaining prevents crashes when a nested property is missing.

const city = data.user?.profile?.address?.city ?? 'Unknown'
const firstRole = data.roles?.[0] ?? 'guest'

Loop through arrays inside nested JSON

Nested arrays are common in API payloads. Parse once, then iterate like normal JavaScript data.

const raw = '{"orders":[{"id":1,"items":[{"sku":"A1"},{"sku":"B2"}]}]}'
const payload = JSON.parse(raw)

for (const order of payload.orders) {
  for (const item of order.items) {
    console.log(item.sku)
  }
}

Handle nested JSON parse errors

A nested payload still fails the same way as any other invalid JSON string. Put the parse intry/catch, then inspect the structure only if parsing succeeded.

try {
  const payload = JSON.parse(raw)
  console.log(payload.user?.profile?.name)
} catch (error) {
  console.error('Invalid JSON', error)
}

If the issue is malformed input, see JSON.parse error JavaScript.

Validate nested data shape

Parsing only proves syntax. Nested APIs often need stronger checks for required arrays, objects, and field types.

if (!Array.isArray(payload.orders)) {
  throw new Error('orders must be an array')
}

if (typeof payload.user?.profile?.name !== 'string') {
  throw new Error('user.profile.name must be a string')
}

For reusable deep validation rules, use JSON Schema examples.

Inspect nested JSON before coding against it

Use Jsonic's JSON Formatter to pretty print deep structures or the JSONPath Tester to query nested fields quickly.

Frequently asked questions

How do I safely access nested JSON properties?

Use optional chaining: data?.user?.profile?.name returns undefinedinstead of throwing if any level is null or missing. Combine with nullish coalescing for defaults: data?.user?.name ?? 'Anonymous'.

What is optional chaining and how does it help?

The ?. operator short-circuits to undefined if the left side isnull or undefined, preventing "Cannot read property of undefined" errors when traversing deep API response structures.

How do I avoid "Cannot read property of undefined"?

Use optional chaining, check parent fields before accessing children, or provide defaults at the parent level: const user = data?.user ?? {} before accessinguser.name.

How do I parse double-serialized JSON?

Call JSON.parse twice. If the first parse returns a string, that string is itself JSON and needs another JSON.parse call to get the object.

How do I flatten a nested JSON object?

Write a recursive function that prefixes child keys with the parent key and a dot, or use the flat npm package. The result maps{ user: { name: "Alice" } } to { "user.name": "Alice" }.

What is JSON Pointer?

JSON Pointer (RFC 6901) is a string like /user/profile/name that identifies a specific value in a JSON document. It is used in JSON Patch operations and JSON Schema$ref. The json-pointer npm package provides get/set helpers.