Round-trip config through text
How to fetch and submit this exercise
Once: install the tool and connect your account.
curl -fsSL https://gonomicon.com/install.sh | sh
gonomicon loginEach exercise: download it, edit the file named in the instructions, then submit.
gonomicon fetch fs-week-2/03-07-roundtrip-config-text
cd 03-07-roundtrip-config-text
gonomicon submitRound-trip config through text
Write functions that save an app configuration object to text and load it back, plus a checker that tells you whether anything was lost along the way.
Worked example
Here's the same save/load pair for a shopping cart:
const cart = {
items: ["pen", "notebook"],
discountCode: undefined,
customer: { name: "Jess", loyalty: { points: 120, tier: "gold" } },
};
function toSavedText(cart) {
return JSON.stringify(cart);
}
function fromSavedText(text) {
return JSON.parse(text);
}
const text = toSavedText(cart);
console.log(text);
const restored = fromSavedText(text);
console.log(restored);
console.log(Object.keys(cart).length, Object.keys(restored).length);
console.log(restored.customer.loyalty.tier);
{"items":["pen","notebook"],"customer":{"name":"Jess","loyalty":{"points":120,"tier":"gold"}}}
{
items: [ 'pen', 'notebook' ],
customer: { name: 'Jess', loyalty: { points: 120, tier: 'gold' } }
}
3 2
gold
cart started with three top-level fields, but discountCode was undefined, and JSON.stringify() quietly left it out of the saved text - so restored only has two fields, not three. Everything else, even three levels deep (customer.loyalty.tier), came back exactly as it was. That gap between 3 and 2 is the thing your roundTrips function needs to notice and report.
Your task
Write function toSavedText(config). Return JSON.stringify(config).
Write function fromSavedText(text). Return JSON.parse(text).
Write function roundTrips(config). Return true only if fromSavedText(toSavedText(config)) is deeply equal to config - same fields, same nested values, all the way down - and false if anything differs, including a field that vanished because its value was undefined.
Rules
roundTripsmust check equality all the way through nested objects and arrays, not just the top level.- A field present in
configwith the valueundefinedmakesroundTripsreturnfalse, because that field won't exist in the restored copy at all. - Two values only count as equal if they're the same type - a number and a numeric-looking string are not interchangeable.
roundTripsdoesn't change theconfigobject it was given.
What you'll practice
Using JSON.stringify and JSON.parse to move data to text and back, and writing your own equality check that walks a nested structure using a loop and a work list, instead of trusting a shortcut that wouldn't catch a silently dropped field.
Run it
gonomicon fetch fs-week-2/03-07-roundtrip-config-text
cd 03-07-roundtrip-config-text
gonomicon test
gonomicon submit
Hints
- toSavedText and fromSavedText are each one line - JSON.stringify and JSON.parse do the whole job.
- For roundTrips, don't write a function that calls itself - instead keep an array you use as a work list of [originalValue, resultValue] pairs still waiting to be checked, and push() the nested pairs you discover onto it as you go, popping one off each time through a loop.
- When you pop a pair: if they're already === equal, move on. Otherwise compare typeof and Array.isArray on both sides first. For two plain objects, Object.keys(x).length must match a Set built from Object.keys(y) (and every one of x's keys must be in that Set) before you push each matching pair of values onto the work list; for two arrays, compare .length first, then push each index's pair.