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 Set s 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 — Set s, WeakSet s, Map s and WeakMap s are ignored or replaced by null . There is hope though — the optional second argument of JSON.stringify() allows us to escape all Set s 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 💋

If you liked this article, please share it on Twitter.

Please enable JavaScript to view the comments powered by Disqus.

Disqus