I realize this is a 5 year old question at this point, but I figured, I'd add my thoughts to it, in case someone runs into a similar use case and finds this useful.
One of the use cases why you would want to flatten a JSON object, is for dynamic template binding via Regular Expression (RegEx) string interpolation. Well wasn't that a mouthful ? It simply translates to "template filling a string without hardcoding".
Ok Imagine a scenario, you have a template string like this for an email:
Hello {{firstName}},
It is amazing you chose to join our site. We are happy to have you on board.
To get started, we would really love it if you can confirm your email address
by clicking on the link: {{confirm_url}}.
Welcome aboard
The Team!
Given the following JSON object in memory:
{
"user" : {
"prefix" : "Dr.",
"firstName" : "Awah",
"lastName" : "Teh",
"email" : "awah@superduperubercoolsite.com",
"address" : {
"street": "100 Main St",
"city" : "PleasantVille",
"state" : "NY",
"phone" : "+1-212-555-1212"
}
},
"meta" : {
"confirm_url" : "http://superduperubercoolsite.com/confirm/ABC123"
}
}
it seems super simple to do a Regular Expression replace like so (assuming our email template string was stored in a variable named template
and the json object was stored in a variable called templateData
:
template = template.replace(new RegExp('{{firstName}}', 'g'), templateData.user.firstName);
template = template.replace(new RegExp('{{confirm_url}}', 'g'), templateData.meta.confirm_url);
Easy right? --> Actually yes! How about this email had 10 templated fields, or you wanted to decouple the template from the code, by storing it in a separate system like SendGrid, where your cool head of marketing can access the template and make changes to the copy-language, without having to call someone from engineering to make changes to the code, test the code and redeploy to production (what a hassle).
This is exactly where flattening of the JSON comes save the day!
Now there are many ways to flatten JSON, I have attached a link to a codepen I wrote that has logic to flatten JSON (actually, I demonstrate two similar but different approaches in the methods flattenJSONIntoKVP
and flattenJSONIntoRAW
check 'em out!).
That said, there are other implementations out there, and it is worth remembering that the focus on this post is to discuss the WHY JSON flattening could be useful, not the HOW.
Moving on! Assume you flattened the JSON from above (using my implementation that results in key value pairs) to something like this:
[
{ "key": "user.prefix", "value": "Dr."},
{ "key": "user.firstName", "value": "Awah"},
{ "key": "user.lastName", "value": "Teh"},
{ "key": "user.email", "value": "awah@superduperubercoolsite.com"},
{ "key": "user.address.street", "value": "100 Main St"},
{ "key": "user.address.city", "value": "{PleasantVille"},
{ "key": "user.address.state", "value": "NY"},
{ "key": "user.address.phone", "value": "+1-212-555-1212"},
{ "key": "meta.confirm_url", "value": "http://superduperubercoolsite.com/confirm/ABC123"},
]
Now, my friend, you are cooking with GAS!
Why, cause now you can dynamically interpolate
the template string with values from the JSON object without giving too much worry to the structure of the JSON (if it changes due to the application evolving, you don't have to also remember to come down here and change this interpolation code -- you simply just have to update the email template itself, which mind you, is on SendGrid [per this example]).
So how to do it you say?: Simple, iteratively. Let's assume that flattened from above was stored in a variable called flatJSON
:
///Notice how I use Javascripts native string interpolation to create my RegExp
///Also note that I am replacing the dot (.) in my flattened JSON variable names with a double underscore (__), I only do this because my intended target is SendGrid, and I don't believe it likes dots in its template placeholders.
flatJSON.forEach(kvp=>template = template.replace(new RegExp(`{{${kvp.key.replace(/\./g, '__'}}}`, 'g'), kvp.value));
That's it, one line of code to replace possibly 10 or even hundreds or even thousands (ok.. maybe not thousands, but you get the point).
Ohh! almost forgot, we need to update our template string.
Notice how now, in our new templated string we can use a somewhat FQDN style variable to map back to our original JSON (Ideally if SendGrid supported dots in their template placeholders, this would look super sweet but alas, can't always win everything!.
Hello {{user__firstName}},
It is amazing you chose to join our site. We are happy to have you on board.
To get started, we would really love it if you can confirm your email address
by clicking on the link: {{meta__confirm_url}}.
Welcome aboard {{user__prefix}} {{user__lastName}}!
The Team!
Et Voila!
Just like that, we have accomplished some good here today; we have:
- Answered the WHY of flattening JSON objects
- We dibble-dabbled into the how, with the codepen example
- And we even overviewed a use case where taking advantage of JSON flattening can help you write durable dynamic code, that evolves as your underlying object structures change -- and that doesn't require you to leverage the big bad ugly
eval
method (we can talk about big bad ugly eval on another post).