Welcome back! 👋 In the previous lesson, you mastered destructuring. Now let's finish the Working with Data Structures section with one of the most practically important topics in all of web development — JSON!
JSON (JavaScript Object Notation) is the universal language of data on the web. Every API you call, every server response you receive, every config file you read — it's JSON. If you want to build anything that talks to the internet, you must understand JSON deeply.
The great news? JSON looks almost exactly like JavaScript objects, so you already know most of it. Let's master it completely!
What is JSON?
JSON is a lightweight, text-based data format for storing and exchanging data. It was designed to be easy for humans to read and easy for machines to parse.
{
"name": "Mihir",
"age": 25,
"city": "Mumbai",
"active": true,
"scores": [92, 85, 78],
"address": {
"state": "Maharashtra",
"pin": "400001"
}
}JSON is just a string — plain text that represents structured data. To use it as a JavaScript object, you need to parse it. To send it somewhere, you need to stringify your object.
JSON vs JavaScript Object
JSON looks like a JS object but has strict rules.
// JavaScript Object — flexible
let user = {
name: "Mihir", // unquoted keys ✅
age: 25,
greet() { return "Hi"; }, // methods allowed ✅
active: true,
nothing: undefined, // undefined allowed ✅
};
// JSON — strict format
let userJSON = `{
"name": "Mihir", // keys MUST be double-quoted
"age": 25,
"active": true
// no methods ❌
// no undefined ❌
// no trailing commas ❌
}`;| Feature | JS Object | JSON |
|---|---|---|
| Key quotes | Optional | Required (double quotes only) |
| String quotes | Single or double | Double quotes only |
| Methods | ✅ Allowed | ❌ Not allowed |
undefined | ✅ Allowed | ❌ Not allowed (omitted) |
| Trailing commas | ✅ Allowed | ❌ Not allowed |
| Comments | ✅ Allowed | ❌ Not allowed |
| Data types | All JS types | String, Number, Boolean, Array, Object, Null |
JSON.stringify() — Object to JSON String
Converts a JavaScript object (or array) into a JSON string. Use this when you want to send data or store it as text.
Basic Usage
let user = {
name: "Mihir",
age: 25,
city: "Mumbai",
active: true,
};
let json = JSON.stringify(user);
console.log(json);
// Output: '{"name":"Mihir","age":25,"city":"Mumbai","active":true}'
console.log(typeof json); // "string"Pretty Print with Indentation
Pass a space value (2 or 4) as the third argument for readable output.
let product = {
name: "Laptop",
price: 55000,
inStock: true,
specs: { ram: "16GB", storage: "512GB" },
};
let prettyJSON = JSON.stringify(product, null, 2);
console.log(prettyJSON);
// Output:
// {
// "name": "Laptop",
// "price": 55000,
// "inStock": true,
// "specs": {
// "ram": "16GB",
// "storage": "512GB"
// }
// }Selective Stringify with Replacer Array
Pass an array of keys to include only specific fields.
let user = {
name: "Mihir",
email: "mihir@example.com",
password: "secret123", // sensitive!
age: 25,
role: "admin",
};
// Only include safe fields
let safeJSON = JSON.stringify(user, ["name", "age", "role"]);
console.log(safeJSON);
// Output: '{"name":"Mihir","age":25,"role":"admin"}'
// password and email excluded ✅What Gets Dropped by JSON.stringify()
let data = {
name: "Mihir",
greet: function() { return "Hi"; }, // ❌ functions — dropped
score: undefined, // ❌ undefined — dropped
temp: null, // ✅ null — kept
active: true, // ✅ boolean — kept
tags: ["js", "dev"], // ✅ array — kept
};
console.log(JSON.stringify(data));
// Output: '{"name":"Mihir","temp":null,"active":true,"tags":["js","dev"]}'
// greet and score are gone!JSON.parse() — JSON String to Object
Converts a JSON string back into a usable JavaScript object. Use this when you receive data from an API or read it from storage.
Basic Usage
let jsonString = '{"name":"Mihir","age":25,"city":"Mumbai","active":true}';
let user = JSON.parse(jsonString);
console.log(user.name); // "Mihir"
console.log(user.age); // 25
console.log(user.active); // true
console.log(typeof user); // "object"Parse Nested JSON
let json = `{
"student": {
"name": "Priya",
"marks": { "math": 92, "science": 88 },
"hobbies": ["coding", "reading", "gaming"]
}
}`;
let data = JSON.parse(json);
console.log(data.student.name); // "Priya"
console.log(data.student.marks.math); // 92
console.log(data.student.hobbies[0]); // "coding"Parse an Array of Objects
let jsonArray = `[
{ "name": "Mihir", "marks": 92 },
{ "name": "Priya", "marks": 85 },
{ "name": "Rahul", "marks": 78 }
]`;
let students = JSON.parse(jsonArray);
console.log(students.length); // 3
console.log(students[0].name); // "Mihir"
// Now you can use all array methods on it!
let topStudents = students.filter(s => s.marks >= 85);
console.log(topStudents.map(s => s.name)); // ["Mihir", "Priya"]Error Handling with JSON
JSON.parse() throws a SyntaxError if the string is not valid JSON. Always wrap it in try...catch.
Without Error Handling — Dangerous
// ❌ Invalid JSON — will crash your program!
let badJSON = "{ name: 'Mihir' }"; // keys not quoted, single quotes
let data = JSON.parse(badJSON); // SyntaxError: Unexpected token n
// Program crashes! ❌With Error Handling — Safe ✅
function safeParseJSON(jsonString) {
try {
return { data: JSON.parse(jsonString), error: null };
} catch (err) {
return { data: null, error: err.message };
}
}
// Valid JSON
let result1 = safeParseJSON('{"name":"Mihir","age":25}');
console.log(result1.data); // { name: "Mihir", age: 25 }
console.log(result1.error); // null
// Invalid JSON
let result2 = safeParseJSON("{ name: 'Mihir' }");
console.log(result2.data); // null
console.log(result2.error); // "Unexpected token n in JSON at position 2"Validate Before Parse
function isValidJSON(str) {
try {
JSON.parse(str);
return true;
} catch {
return false;
}
}
console.log(isValidJSON('{"name":"Mihir"}')); // true
console.log(isValidJSON("{ name: Mihir }")); // false
console.log(isValidJSON("[1, 2, 3]")); // true
console.log(isValidJSON("just a string")); // falseDeep Cloning with JSON
A quick and common way to deep clone a plain object — no nested reference issues.
let original = {
name: "Mihir",
scores: [92, 85, 78],
address: { city: "Mumbai" },
};
// Shallow copy — nested objects still shared
let shallow = { ...original };
shallow.address.city = "Pune";
console.log(original.address.city); // "Pune" — oops! ❌
// Deep clone via JSON — fully independent
let deep = JSON.parse(JSON.stringify(original));
deep.address.city = "Delhi";
console.log(original.address.city); // "Mumbai" — safe ✅⚠️ Limitations of JSON Deep Clone
let obj = {
name: "Mihir",
greet: function() { return "Hi"; }, // ❌ functions — lost after clone
created: new Date(), // ❌ Date becomes string after clone
nothing: undefined, // ❌ undefined — lost after clone
};
let clone = JSON.parse(JSON.stringify(obj));
console.log(clone.greet); // undefined — function lost!
console.log(clone.created); // "2024-02-13T..." — string, not Date!
console.log(clone.nothing); // undefined — key lost!
// ✅ Only use JSON clone for plain data objects — no functions, Dates, or undefinedJSON with Fetch API
In real projects, you'll mostly encounter JSON when fetching data from APIs. Here's the complete pattern.
Reading JSON from a Fetch Response
// Standard fetch + JSON pattern
async function getUsers() {
try {
let response = await fetch("https://jsonplaceholder.typicode.com/users");
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
let users = await response.json(); // automatically parses JSON ✅
console.log(`Fetched ${users.length} users`);
return users;
} catch (err) {
console.error("Failed to fetch:", err.message);
return [];
}
}Sending JSON with POST
async function createUser(userData) {
try {
let response = await fetch("https://api.example.com/users", {
method: "POST",
headers: {
"Content-Type": "application/json", // tell server we're sending JSON
},
body: JSON.stringify(userData), // convert object to JSON string
});
let result = await response.json();
console.log("Created:", result);
return result;
} catch (err) {
console.error("Failed to create user:", err.message);
}
}
createUser({ name: "Mihir", email: "mihir@example.com", role: "admin" });Simulating a Full API Workflow (Without Network)
// Simulate: API response as a raw JSON string
let rawResponse = `{
"status": 200,
"message": "OK",
"data": {
"users": [
{ "id": 1, "name": "Mihir", "role": "admin", "active": true },
{ "id": 2, "name": "Priya", "role": "editor", "active": true },
{ "id": 3, "name": "Rahul", "role": "viewer", "active": false }
],
"total": 3,
"page": 1
}
}`;
// Step 1: Parse the JSON
let response = JSON.parse(rawResponse);
// Step 2: Destructure what you need
let { status, data: { users, total } } = response;
// Step 3: Process
let activeUsers = users.filter(u => u.active);
console.log(`Status: ${status}`);
console.log(`Total Users: ${total}`);
console.log(`Active: ${activeUsers.length}`);
activeUsers.forEach(u => console.log(` [${u.role}] ${u.name}`));
// Output:
// Status: 200
// Total Users: 3
// Active: 2
// [admin] Mihir
// [editor] PriyaJSON with localStorage
Browsers only store strings in localStorage — so use JSON to save and load objects.
// Save object to localStorage
function saveToStorage(key, value) {
try {
localStorage.setItem(key, JSON.stringify(value));
console.log(`✅ Saved "${key}" to storage`);
} catch (err) {
console.error("Failed to save:", err.message);
}
}
// Load object from localStorage
function loadFromStorage(key, defaultValue = null) {
try {
let raw = localStorage.getItem(key);
return raw ? JSON.parse(raw) : defaultValue;
} catch (err) {
console.error("Failed to load:", err.message);
return defaultValue;
}
}
// Usage
let userPrefs = { theme: "dark", fontSize: 16, language: "en" };
saveToStorage("userPrefs", userPrefs);
let loaded = loadFromStorage("userPrefs", { theme: "light" });
console.log(loaded.theme); // "dark"
// List not found — returns default
let missing = loadFromStorage("notExist", []);
console.log(missing); // []Transforming JSON Data
Real-world API JSON often needs transformation before use.
Rename Keys (snake_case → camelCase)
let apiData = [
{ user_id: 1, first_name: "Mihir", last_name: "Shah", is_active: true },
{ user_id: 2, first_name: "Priya", last_name: "Nair", is_active: false },
{ user_id: 3, first_name: "Rahul", last_name: "Gupta", is_active: true },
];
let cleanData = apiData.map(({
user_id: id,
first_name: firstName,
last_name: lastName,
is_active: isActive,
}) => ({
id,
name: `${firstName} ${lastName}`,
isActive,
initials: `${firstName[0]}${lastName[0]}`.toUpperCase(),
}));
console.log(JSON.stringify(cleanData, null, 2));
// [
// { "id": 1, "name": "Mihir Shah", "isActive": true, "initials": "MS" },
// { "id": 2, "name": "Priya Nair", "isActive": false, "initials": "PN" },
// { "id": 3, "name": "Rahul Gupta", "isActive": true, "initials": "RG" }
// ]Filter and Reshape
let rawProducts = `[
{ "id": 1, "title": "Laptop", "price": 55000, "category": "electronics", "stock": 5 },
{ "id": 2, "title": "T-Shirt", "price": 799, "category": "clothing", "stock": 0 },
{ "id": 3, "title": "Phone", "price": 18000, "category": "electronics", "stock": 12 },
{ "id": 4, "title": "Jeans", "price": 1499, "category": "clothing", "stock": 8 }
]`;
let products = JSON.parse(rawProducts);
let catalogue = products
.filter(p => p.stock > 0)
.map(({ id, title, price, category }) => ({
id,
name: title,
price: `₹${price.toLocaleString()}`,
category: category.charAt(0).toUpperCase() + category.slice(1),
inStock: true,
}));
console.log(JSON.stringify(catalogue, null, 2));
// [
// { "id": 1, "name": "Laptop", "price": "₹55,000", "category": "Electronics", "inStock": true },
// { "id": 3, "name": "Phone", "price": "₹18,000", "category": "Electronics", "inStock": true },
// { "id": 4, "name": "Jeans", "price": "₹1,499", "category": "Clothing", "inStock": true }
// ]Real-World Examples
Example 1: Config File Manager
// Simulated config.json content
let configJSON = `{
"app": {
"name": "LearnJS",
"version": "2.1.0",
"environment": "production"
},
"database": {
"host": "db.learnjs.com",
"port": 5432,
"name": "learnjs_prod"
},
"features": {
"darkMode": true,
"notifications": true,
"analytics": false
},
"limits": {
"maxUploadMB": 10,
"sessionMinutes": 60,
"maxLoginAttempts": 3
}
}`;
let config = JSON.parse(configJSON);
// Destructure what you need
let { app, features, limits } = config;
console.log(`🚀 ${app.name} v${app.version} [${app.environment}]`);
console.log(`\n📌 Features:`);
for (let [feature, enabled] of Object.entries(features)) {
console.log(` ${feature.padEnd(18)}: ${enabled ? "✅ On" : "❌ Off"}`);
}
console.log(`\n⚙️ Limits:`);
for (let [limit, value] of Object.entries(limits)) {
console.log(` ${limit.padEnd(20)}: ${value}`);
}
// Output:
// 🚀 LearnJS v2.1.0 [production]
// 📌 Features:
// darkMode : ✅ On
// notifications : ✅ On
// analytics : ❌ Off
// ⚙️ Limits:
// maxUploadMB : 10
// sessionMinutes : 60
// maxLoginAttempts : 3Example 2: Student Data Pipeline
// Raw JSON from a database
let rawJSON = `{
"semester": "Spring 2024",
"students": [
{ "id": "S001", "name": "Mihir", "scores": { "math": 92, "science": 88, "english": 85 } },
{ "id": "S002", "name": "Priya", "scores": { "math": 78, "science": 91, "english": 82 } },
{ "id": "S003", "name": "Rahul", "scores": { "math": 65, "science": 70, "english": 60 } },
{ "id": "S004", "name": "Sara", "scores": { "math": 95, "science": 93, "english": 90 } },
{ "id": "S005", "name": "Arjun", "scores": { "math": 55, "science": 60, "english": 50 } }
]
}`;
let { semester, students } = JSON.parse(rawJSON);
// Process
let report = students.map(({ id, name, scores }) => {
let values = Object.values(scores);
let average = (values.reduce((s, n) => s + n, 0) / values.length).toFixed(1);
let grade = average >= 90 ? "A" : average >= 75 ? "B" : average >= 60 ? "C" : "F";
let status = average >= 60 ? "Pass ✅" : "Fail ❌";
return { id, name, average: parseFloat(average), grade, status };
});
let classAvg = (
report.reduce((s, s2) => s + s2.average, 0) / report.length
).toFixed(1);
// Display
console.log(`\n📚 ${semester} — Student Report`);
console.log("=".repeat(55));
report
.sort((a, b) => b.average - a.average)
.forEach(({ id, name, average, grade, status }, i) => {
console.log(`${i + 1}. [${id}] ${name.padEnd(8)} Avg: ${average} | ${grade} | ${status}`);
});
console.log("=".repeat(55));
console.log(`Class Average: ${classAvg}`);
// Serialize back to JSON for storage/API
let outputJSON = JSON.stringify({ semester, report, classAvg }, null, 2);
console.log("\n📤 Output JSON (first 200 chars):");
console.log(outputJSON.slice(0, 200) + "...");Example 3: Shopping Cart with Persistence
// Simulate browser localStorage with a plain object
let fakeStorage = {};
const storage = {
getItem: key => fakeStorage[key] ?? null,
setItem: (key, val) => { fakeStorage[key] = val; },
removeItem: key => { delete fakeStorage[key]; },
};
// Cart manager with JSON persistence
let cartManager = {
STORAGE_KEY: "shopping_cart",
load() {
try {
let raw = storage.getItem(this.STORAGE_KEY);
return raw ? JSON.parse(raw) : [];
} catch {
return [];
}
},
save(cart) {
storage.setItem(this.STORAGE_KEY, JSON.stringify(cart));
},
add(item) {
let cart = this.load();
let existing = cart.find(i => i.id === item.id);
if (existing) {
existing.qty += 1;
console.log(`🔄 Updated qty: ${item.name} (${existing.qty})`);
} else {
cart.push({ ...item, qty: 1 });
console.log(`✅ Added: ${item.name}`);
}
this.save(cart);
},
remove(id) {
let cart = this.load().filter(i => i.id !== id);
this.save(cart);
console.log(`🗑️ Removed item #${id}`);
},
summary() {
let cart = this.load();
let total = cart.reduce((s, i) => s + i.price * i.qty, 0);
console.log("\n🛒 Cart:");
cart.forEach(({ name, price, qty }) => {
console.log(` ${name.padEnd(14)} ₹${price} × ${qty} = ₹${price * qty}`);
});
console.log(` ${"─".repeat(38)}`);
console.log(` TOTAL: ₹${total.toLocaleString()}`);
},
};
cartManager.add({ id: 1, name: "Laptop", price: 55000 });
cartManager.add({ id: 2, name: "Mouse", price: 800 });
cartManager.add({ id: 3, name: "Keyboard", price: 1500 });
cartManager.add({ id: 1, name: "Laptop", price: 55000 }); // qty++
cartManager.remove(2);
cartManager.summary();
// Output:
// ✅ Added: Laptop
// ✅ Added: Mouse
// ✅ Added: Keyboard
// 🔄 Updated qty: Laptop (2)
// 🗑️ Removed item #2
// 🛒 Cart:
// Laptop ₹55000 × 2 = ₹110000
// Keyboard ₹1500 × 1 = ₹1500
// ──────────────────────────────────────
// TOTAL: ₹1,11,500Common Mistakes
Mistake 1: Parsing Already-Parsed Data
let user = { name: "Mihir", age: 25 }; // Already a JS object
// ❌ Don't parse an object — it's not a JSON string!
let parsed = JSON.parse(user);
// Returns "[object Object]" as parsed — wrong!
// ✅ Only parse strings
let jsonString = '{"name":"Mihir","age":25}';
let parsed = JSON.parse(jsonString); // ✅Mistake 2: Invalid JSON Syntax
// These are NOT valid JSON:
// ❌ Single quotes
JSON.parse("{'name': 'Mihir'}"); // SyntaxError
// ❌ Unquoted keys
JSON.parse("{name: 'Mihir'}"); // SyntaxError
// ❌ Trailing comma
JSON.parse('{"name":"Mihir","age":25,}'); // SyntaxError
// ❌ Comments
JSON.parse('{"name":"Mihir" // user name }'); // SyntaxError
// ✅ Valid JSON only
JSON.parse('{"name":"Mihir","age":25}'); // ✅Mistake 3: Forgetting try...catch Around JSON.parse()
// ❌ No error handling — one bad string crashes everything
function processData(jsonStr) {
let data = JSON.parse(jsonStr); // could throw!
return data.users;
}
// ✅ Always wrap JSON.parse in try...catch
function processData(jsonStr) {
try {
let data = JSON.parse(jsonStr);
return data.users ?? [];
} catch (err) {
console.error("Invalid JSON:", err.message);
return [];
}
}Mistake 4: Expecting Functions and undefined to Survive Stringify
let user = {
name: "Mihir",
greet: () => "Hello", // function
score: undefined, // undefined
active: true,
};
let json = JSON.stringify(user);
console.log(json);
// '{"name":"Mihir","active":true}'
// greet and score are silently GONE! ❌
// ✅ Be explicit — if a value might be undefined, set it to null
let safeUser = {
name: "Mihir",
score: null, // null survives stringify
active: true,
};
JSON.stringify(safeUser);
// '{"name":"Mihir","score":null,"active":true}' ✅Mistake 5: Mutating a Parsed Object and Expecting JSON to Update
let jsonStr = '{"name":"Mihir","count":0}';
let obj = JSON.parse(jsonStr);
obj.count = 99; // ✅ modifies the JS object
// ❌ jsonStr is still the original string — it doesn't auto-update!
console.log(jsonStr); // '{"name":"Mihir","count":0}' — unchanged
// ✅ Re-stringify to get updated JSON
let updatedJSON = JSON.stringify(obj);
console.log(updatedJSON); // '{"name":"Mihir","count":99}' ✅Practical Exercise
Create a file called working-with-json.js:
// 🎯 Working with JSON Practice
// 1. Parse and process a product catalog
console.log("=== 🛍️ Product Catalog ===");
let catalogJSON = `{
"store": "TechMart",
"lastUpdated": "2024-02-13",
"products": [
{ "id": 1, "name": "Laptop", "price": 55000, "category": "Electronics", "stock": 5, "rating": 4.5 },
{ "id": 2, "name": "T-Shirt", "price": 799, "category": "Clothing", "stock": 20, "rating": 4.1 },
{ "id": 3, "name": "Phone", "price": 18000, "category": "Electronics", "stock": 0, "rating": 4.8 },
{ "id": 4, "name": "Sneakers", "price": 3999, "category": "Footwear", "stock": 8, "rating": 4.3 },
{ "id": 5, "name": "Earbuds", "price": 2500, "category": "Electronics", "stock": 15, "rating": 4.6 }
]
}`;
let { store, products } = JSON.parse(catalogJSON);
let inStock = products.filter(p => p.stock > 0);
let electronics = inStock.filter(p => p.category === "Electronics");
let totalValue = products.reduce((s, p) => s + p.price * p.stock, 0);
let topRated = [...products].sort((a, b) => b.rating - a.rating)[0];
console.log(`Store: ${store}`);
console.log(`In Stock: ${inStock.length}/${products.length} products`);
console.log(`Electronics available: ${electronics.map(p => p.name).join(", ")}`);
console.log(`Total Inventory Value: ₹${totalValue.toLocaleString()}`);
console.log(`Top Rated: ${topRated.name} (⭐${topRated.rating})`);
// 2. Safe JSON parser with validation
console.log("\n=== 🛡️ Safe JSON Parser ===");
function safeParseJSON(str, fallback = null) {
try {
let parsed = JSON.parse(str);
return { success: true, data: parsed, error: null };
} catch (err) {
return { success: false, data: fallback, error: err.message };
}
}
let tests = [
'{"name":"Mihir","age":25}',
"[1, 2, 3, 4, 5]",
"{ name: Mihir }", // invalid
'{"active":true,"score":null}',
"not json at all", // invalid
];
tests.forEach(test => {
let { success, data, error } = safeParseJSON(test);
console.log(success
? `✅ Valid | ${JSON.stringify(data)}`
: `❌ Invalid| ${error.split(" ").slice(0, 5).join(" ")}...`
);
});
// 3. Build, save, and reload a gradebook
console.log("\n=== 📚 Gradebook Persistence ===");
let fakeStorage = {};
function saveData(key, data) {
fakeStorage[key] = JSON.stringify(data);
console.log(`💾 Saved "${key}"`);
}
function loadData(key, fallback = null) {
let raw = fakeStorage[key];
return raw ? JSON.parse(raw) : fallback;
}
let gradebook = {
class: "JavaScript 101",
term: "Spring 2024",
students: [
{ name: "Mihir", scores: [92, 88, 95, 90] },
{ name: "Priya", scores: [78, 82, 85, 80] },
{ name: "Rahul", scores: [60, 55, 65, 70] },
],
};
// Add computed fields before saving
gradebook.students = gradebook.students.map(s => {
let avg = (s.scores.reduce((a, b) => a + b, 0) / s.scores.length).toFixed(1);
let grade = avg >= 90 ? "A" : avg >= 75 ? "B" : avg >= 60 ? "C" : "F";
return { ...s, average: parseFloat(avg), grade };
});
saveData("gradebook", gradebook);
// Reload and display
let loaded = loadData("gradebook");
console.log(`\nLoaded: ${loaded.class} — ${loaded.term}`);
loaded.students
.sort((a, b) => b.average - a.average)
.forEach(({ name, average, grade }, i) => {
console.log(` ${i + 1}. ${name.padEnd(8)} Avg: ${average} | Grade: ${grade}`);
});Run it:
node working-with-json.jsExpected Output:
=== 🛍️ Product Catalog ===
Store: TechMart
In Stock: 4/5 products
Electronics available: Laptop, Earbuds
Total Inventory Value: ₹3,44,480
Top Rated: Phone (⭐4.8)
=== 🛡️ Safe JSON Parser ===
✅ Valid | {"name":"Mihir","age":25}
✅ Valid | [1,2,3,4,5]
❌ Invalid| Unexpected token n in JSON...
✅ Valid | {"active":true,"score":null}
❌ Invalid| Unexpected token o in JSON...
=== 📚 Gradebook Persistence ===
💾 Saved "gradebook"
Loaded: JavaScript 101 — Spring 2024
1. Mihir Avg: 91.3 | Grade: A
2. Priya Avg: 81.3 | Grade: B
3. Rahul Avg: 62.5 | Grade: CKey Takeaways
Congratulations! 🎉 You now fully understand how to work with JSON in JavaScript.
✅ JSON is a text-based data format — a string, not an object. It's the universal language of data exchange on the web.
✅ JSON.stringify(obj) — converts a JS object to a JSON string. Functions and undefined are dropped silently.
✅ JSON.parse(str) — converts a JSON string to a JS object. Always wrap in try...catch.
✅ Pretty print — JSON.stringify(obj, null, 2) for readable, indented output.
✅ Selective stringify — pass an array of keys as the second argument to include only specific fields.
✅ Error handling — invalid JSON throws SyntaxError. Always guard with try...catch in production.
✅ Deep clone — JSON.parse(JSON.stringify(obj)) for plain objects. Loses functions, Dates, and undefined.
✅ With Fetch — response.json() automatically parses. JSON.stringify(data) for POST body.
✅ With localStorage — always stringify before saving, parse after loading.
Best Practices
- ✅ Always use
try...catcharoundJSON.parse()— never assume the input is valid - ✅ Use
JSON.stringify(data, null, 2)when logging or debugging — much easier to read - ✅ Use the replacer array to exclude sensitive fields before sending JSON
- ✅ Use
nullinstead ofundefinedfor missing values —undefinedgets dropped by stringify - ✅ Only use JSON deep clone for plain data objects — not for objects with methods or Dates
- ✅ Always set
Content-Type: application/jsonheader when sending JSON to an API - ✅ Validate API responses before destructuring — don't assume the shape is always correct
- ✅ Build a
safeParseJSONutility function in your projects — use it everywhere instead of rawJSON.parse
🎉 Working with Data Structures — Section Complete!
Amazing work! You've now completed the entire Working with Data Structures section! Here's everything you've mastered:
| Topic | What You Learned |
|---|---|
| Strings | Methods, search, slice, replace, split/join |
| Template Literals | Interpolation, multi-line, tagged templates |
| Arrays | CRUD, map/filter/reduce, sort, spread |
| Loops with Arrays | Patterns, for...of, forEach, break/continue |
| Map, Filter, Reduce | Transform, filter, accumulate, chaining |
| Objects | Keys/values, methods, this, Object.* helpers |
| Destructuring | Arrays, objects, nested, params, defaults |
| JSON | Parse, stringify, fetch, error handling |