Skip to content
Advertisement

Turn an object to a square bracket string (not using JSON.stringify)

I have this Javascript object (that is created on-the-fly by my plugin code):

{
   "field": {
      "name": "Name",
      "surname": "Surname"
   },
   "address": {
      "street": "Street",
      "number": 0,
      "postcode": 0,
      "geo": {
        "city": "City",
        "country": "Country",   
        "state": "State"   
      }
   },
   "options": [1,4,6,8,11]
 }

I don’t want to turn this object to a JSON string, but I want to turn this object into another object, but with each field represented by a string, like this:

{
  "field[name]": "Name",
  "field[surname]": "Surname",
  "address[street]": "Street",
  "address[number]": 0,
  "address[postcode]": 0,
  "address[geo][city]": "City",
  "address[geo][country]": "Country",   
  "address[geo][state]": "State",   
  "options[0]":1,
  "options[1]":4,
  "options[2]":6,
  "options[3]":8,
  "options[4]":11
}

Scenario:

  • I dont know how the original object will look like (or how deep it’ll be), since it’s part of a plugin and I have no idea how people will build their forms
  • I’m going to put this new object inside a FormData object, if it would only accept objects, it would be easier, because JSON can’t upload files, but FormData object can

Advertisement

Answer

As I said in the comments, you need a for...in [MDN] loop to iterate over the properties of the object and can use recursion to subsequently convert nested objects:

function convert(obj, prefix, result) {
    result = result || {};

    // iterate over all properties
    for (var prop in obj) {
        if (obj.hasOwnProperty(prop)) {
            var value = obj[prop];
            // build the property name for the result object
            // first level is without square brackets
            var name = prefix ? prefix + '[' + prop + ']' : prop;
            if (typeof value !== 'object') {
                // not an object, add value to final result
                result[name] = value;
            }
            else {
                // object, go deeper
                convert(value, name, result);
            }
        }
    }

    return result;
}

// Usage:
var converted_data = convert(data);

DEMO

Still, I would recommend using JSON.

If you want to handle files as well, you might have to add an additional check for File objects. You’d want them raw in the result object:

else if (window.File && value instanceof File) {
    result[name] = value;
}

// and for file lists

else if (window.FileList && value instanceof FileList) {
    for (var i = 0, l = value.length; i < l; i++) {
        result[name + '[' + i + ']'] = value.item(i);
    }
}

It could be that the File (FileList) constructor is named differently in IE, but it should give you a start.

User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement