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, butFormData
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);
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.