Site icon Codisfy

Flatten JavaScript Object for use with FormData

You are currently viewing the Mobile Optimized version (AMP), some features may be missing or may not work as expected. Open Full Version.

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.