Skip to content

TIL — The power of JSON.stringify replacer parameter

I had an interesting problem that melted my brain a bit. Let me share what I have learned and maybe save you a few moments when you come across a similar challenge. Lets have some fun with JSON.stringify().

const dude = {
  name: "Pawel",
  friends: ["Dan", "Pedro", "Mr Gregory"]
};
const dudeStringified = JSON.stringify(dude);

console.log(dudeStringified);
// {"name":"Pawel","friends":["Dan","Pedro","Mr Gregory"]}

No surprises here. Unfortunately, the architecture used on my project (AWS DynamoDB for curious beasts) forced me to deal with ECMAScript Sets and things became more interesting. Just look at this.

const dude = {
  name: "Pawel",
  friends: new Set(["Dan", "Pedro", "Mr Gregory"])
};
const dudeStringified = JSON.stringify(dude);

console.log(dudeStringified);
// {"name":"Pawel","friends":{}}

I assumed that a set of values is going to be converted to a good old plain array. As you may have guessed I was wrong — Sets, WeakSets, Maps and WeakMaps are ignored or replaced by null. There is hope though — the optional second argument of JSON.stringify() allows us to escape all Sets and convert them to an array.

const dude = {
  name: "Pawel",
  friends: new Set(["Dan", "Pedro", "Mr Gregory"])
};
const dudeStringified = JSON.stringify(dude, (key, value) =>
  value instanceof Set ? [...value] : value
);

console.log(dudeStringified);
// {"name":"Pawel","friends":["Dan","Pedro","Mr Gregory"]}

Problem solved 👏

(TIL) Today I learned

JSON.stringify() takes a second optional argument that can be a recursive replacer function or an array of white-listed keys to be stringified. Like so…

// Second argument as a replacer function

const dude = {
  name: "Dan"
};
const dudeStringified = JSON.stringify(dude, (key, value) =>
  key === "name" ? "Pawel" : value
);

console.log(dudeStringified);
// {"name":"Pawel"}
// Second argument as an array of white-listed keywords

const dude = {
  name: "Pawel",
  friends: new Set(["Dan", "Pedro", "Mr Gregory"])
};

const dudeStringified = JSON.stringify(dude, ["name"]);

console.log(dudeStringified);
// {"name":"Pawel"}

Third argument can be a string or a number. It decides about the number of spaces or text to used as a delimiter. Look!

// Third argument as a number

const dude = {
  name: "Pawel",
  friends: ["Dan", "Pedro", "Mr Gregory"]
};
const dudeStringified = JSON.stringify(dude, null, 4);

console.log(dudeStringified);
// {
//   "name": "Pawel",
//   "friends": [
//       "Dan",
//       "Pedro",
//       "Mr Gregory"
//   ]
// }
// Third argument as a string

const dude = {
  name: "Pawel",
  friends: ["Dan", "Pedro", "Mr Gregory"]
};
const dudeStringified = JSON.stringify(dude, null, "🍆");

console.log(dudeStringified);
// {
// 🍆"name": "Pawel",
// 🍆"friends": [
// 🍆🍆"Dan",
// 🍆🍆"Pedro",
// 🍆🍆"Mr Gregory"
// 🍆]
// }

Until next time, stay curious 💋

comments powered by Disqus