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.