Before this lesson

Understand objects, arrays, JSON strings and DOM events. Run storage examples in a separate practice page.

What you will be able to do

Design a validated persistent format and recover when stored data is malformed.

Understand the mechanism

JSON represents strings, numbers, booleans, null, arrays and objects, not complete functions, undefined, circular references or prototypes. stringify serializes and parse reconstructs ordinary data. Successful parsing verifies syntax, not application field types.

localStorage stores strings synchronously per origin. Other same-origin pages and the user can change it. Quotas or browser policies can cause failures, so catch them while keeping the current page usable. It is neither secure credential storage nor a cross-device database.

Namespace and version keys to reduce collisions, and validate fields after loading. Migrations identify a version before converting older shapes. Do not assume unknown versions are compatible. Remove only your key rather than clearing all same-origin storage.

Runnable example

const KEY = "honeysuck-demo:progress:v1";
function loadProgress() {
  try {
    const data = JSON.parse(localStorage.getItem(KEY) ?? "null");
    return data && data.version === 1 && Array.isArray(data.done)
      ? data.done.filter(id => Number.isInteger(id) && id > 0) : [];
  } catch { return []; }
}
function saveProgress(done) {
  try {
    localStorage.setItem(KEY, JSON.stringify({ version: 1, done }));
    return true;
  } catch { return false; }
}
console.log(saveProgress([1, 3]), loadProgress());

Trace and verify

Run in a same-origin page console and read back 1 and 3. Replace the key with malformed JSON and confirm loading returns an empty array. Then test valid JSON with an invalid done field to verify schema checks.

Common mistakes and boundaries

Returning an empty array permits recovery, but a product should also report failed saves. Concurrent tabs can overwrite each other; storage events notify changes but do not provide transactions.

Practice challenge

Deduplicate IDs on load and add a reset action that removes only this progress key.

Reference solution and reasoning

Deduplicate validated IDs with Set. Reset with removeItem(KEY), then update memory and UI; retain error handling around storage.

Further reading