Flatten JavaScript Object for use with FormData
This is something I thought that no one would ever need but looking at this gist. The stars, forks and comments proved me wrong.
I needed to flatten an object as well as wanted to send over some data from a VueJS frontend as multipart/form-data and on the backend it was PHP so I needed the field names to be like
"name" : "value", "nested[0][name]": "value", "nested[0][age]": "value"
The comments in the gist had the following function which I modified a bit to be like:
/**
* Flatten object to be of form key[subkey] for sending in multipart/form-data
* Use for simple data types, with multi level nesting
* @param {*} object
*/
flatten(object) {
return Object.assign({}, ...function _flatten(objectBit, path = '', left =
"[", right = "]") {
return [].concat(
...Object.keys(objectBit).map(
key => typeof objectBit[key] === 'object' ?
_flatten(objectBit[key], `${path}${left}${key}${right}`) :
({
[`${path}${left}${key}${right}`]: objectBit[key]
}) //append object with it’s path as key
)
)
}(object, '', '', ''));
}
I added the left, right variables. As I didn’t need the brackets for the very first level, I put left and right as ” for the very first call to _flatten. The variables give more flexibility as I can change them later to get output likenested.0.name or /nested/0/name by playing around with them.
This function allows me to call it like:
flatten({
"id": 3,
"name": "Montserrat",
"signatures": [
{
"name": "Susanna Towne",
"image_url": "https://lorempixel.com/50/50/?90502"
},
{
"name": "Tremaine Durgan",
"image_url": "https://lorempixel.com/50/50/?79275"
},
{
"name": "Dr. Julia Block",
"image_url": "blob:http://localhost:8000/def8a73e-c437-4d5c-bef8-3e7b44605928"
},
{
"name": "Victoria Keebler",
"image_url": "https://lorempixel.com/50/50/?83540"
},
{
"name": {
"abc": "xyz"
},
"image_url": "blob:http://localhost:8000/6caf4ce1-8084-409b-82c1-7ede1e72f3c9"
}
]
});
and get output as:
{
"id": 3,
"name": "Montserrat",
"signatures[0][name]": "Susanna Towne",
"signatures[0][image_url]": "https://lorempixel.com/50/50/?90502",
"signatures[1][name]": "Tremaine Durgan",
"signatures[1][image_url]": "https://lorempixel.com/50/50/?79275",
"signatures[2][name]": "Dr. Julia Block",
"signatures[2][image_url]": "blob:http://localhost:8000/def8a73e-c437-4d5c-bef8-3e7b44605928",
"signatures[3][name]": "Victoria Keebler",
"signatures[3][image_url]": "https://lorempixel.com/50/50/?83540",
"signatures[4][name][abc]": "xyz",
"signatures[4][image_url]": "blob:http://localhost:8000/6caf4ce1-8084-409b-82c1-7ede1e72f3c9"
}
Check how it even goes below level 1 of nesting and the output is exactly what I wanted.
