183

How do I convert the entries from a HTML5 FormData object to JSON?

The solution should not use jQuery. Also, it should not simply serialize the entire FormData object, but only its key/value entries.

janw
  • 7,168
  • 9
  • 31
  • 54
Leonardo Villela
  • 1,958
  • 2
  • 11
  • 9

27 Answers27

265

You could also use forEach on the FormData object directly:

var object = {};
formData.forEach(function(value, key){
    object[key] = value;
});
var json = JSON.stringify(object);

UPDATE:

And for those who prefer the same solution with ES6 arrow functions:

var object = {};
formData.forEach((value, key) => object[key] = value);
var json = JSON.stringify(object);

UPDATE 2:

And for those who want support for multi select lists or other form elements with multiple values (since there are so many comments below the answer regarding this issue I will add a possible solution):

var object = {};
formData.forEach((value, key) => {
    // Reflect.has in favor of: object.hasOwnProperty(key)
    if(!Reflect.has(object, key)){
        object[key] = value;
        return;
    }
    if(!Array.isArray(object[key])){
        object[key] = [object[key]];    
    }
    object[key].push(value);
});
var json = JSON.stringify(object);

Here a Fiddle demonstrating the use of this method with a simple multi select list.

UPDATE 3:

As a side note for those ending up here, in case the purpose of converting the form data to json is to send it through a XML HTTP request to a server you can send the FormData object directly without converting it. As simple as this:

var request = new XMLHttpRequest();
request.open("POST", "http://example.com/submitform.php");
request.send(formData);

See also Using FormData Objects on MDN for reference:

UPDATE 4:

As mentioned in one of the comments below my answer the JSON stringify method won't work out of the box for all types of objects. For more information on what types are supported I would like to refer to the Description section in the MDN documentation of JSON.stringify.

In the description is also mentioned that:

If the value has a toJSON() method, it's responsible to define what data will be serialized.

This means that you can supply your own toJSON serialization method with logic for serializing your custom objects. Like that you can quickly and easily build serialization support for more complex object trees.

Nilpo
  • 4,502
  • 1
  • 23
  • 38
Wilt
  • 37,062
  • 11
  • 138
  • 192
  • 1
    As mentioned in the answer from @TomasPrado make sure you don't need support for IE11. – Wilt Feb 23 '18 at 08:44
  • 5
    This doesn't work with multi select form elements since they share the same key you end up overwriting the values returning only the last selected element – Sean Apr 02 '18 at 05:18
  • 1
    @Sean I gave an answer that works with multiple values for `` with same name, by converting the value to an array. – some Apr 14 '18 at 00:32
  • formData is not a serie. how you can iterate? accepted answer but something missed. – Nuri YILMAZ Jun 28 '18 at 15:24
  • @mayank In which browser does it not work? If you are using internet explorer 11 or older then it was already mentioned in a comment earlier... – Wilt Nov 27 '18 at 20:07
  • Chrome V-70, foreach need to be added as prototype function to formData. than only I can use. – Mayank Nov 27 '18 at 23:33
  • If you are using `fetch` with this, make sure you use the correct headers with `application/json` – Pro Q Feb 24 '19 at 05:05
  • when input has same name, this method going bad ,that only last element input shows. why this > – Dhanushka sasanka Jul 23 '19 at 20:53
  • @Dhanushkasasanka It happens because elements with the same key end up overwriting each other. See also the other comments. I added another update that should resolve this problem. – Wilt Jul 27 '19 at 07:22
  • Accepted answer and does not convert the value to the appropriate type? What if the value is a BLOB or a File type? – Mohy Eldeen Sep 30 '19 at 22:15
  • @MohyEldeen JSON `stringify` will not work for all types, I would like to refer [to this answer](https://stackoverflow.com/a/29281243/1697459) on another question that might help you solve your issue. One suggestion is to add a `toJSON` method to your object, I hope it will be of help. – Wilt Oct 01 '19 at 07:31
  • 13
    Unless a need for multi selects etc.. the answer with `JSON.stringify(Object.fromEntries(formData));` is so much nicer – Tom Stickel Nov 06 '19 at 21:15
  • It's ridiculous that it doesn't have a helper that does this. This should not be this difficult. – user2490003 Apr 15 '20 at 18:44
  • @Wilt, please add that in your UPDATE 2 code will be some problem with input name. If i make name for input with square brackets, this brackets will send to server. But if we use standard form submit, php will receive name without brackets. – Emil Sabitov May 17 '20 at 14:46
  • does not convert field if you have input type file on the form – sairfan Jul 24 '20 at 20:02
214

In 2019, this kind of task became super-easy.

JSON.stringify(Object.fromEntries(formData));

Object.fromEntries: Supported in Chrome 73+, Firefox 63+, Safari 12.1

As mentioned in the comments, please note: FormData can contain multiple values with the same key (e.g. checkboxes with the same name). Object.fromEntries() throws away duplicates and only keeps the last one.

smhg
  • 2,151
  • 18
  • 26
hakatashi
  • 7,447
  • 2
  • 19
  • 21
  • 3
    Came here to post this, love looking at this thread and seeing how answers have evolved during the years – Marcin Apr 27 '19 at 16:33
  • 23
    This doesn't seem to work correctly on forms that have multiple fields with same name. – JukkaP Sep 08 '19 at 18:05
  • 6
    It is 2020 and this do not handle multiple selected values of `` – some Jan 02 '20 at 05:11
  • 7
    Better to use formData.entries: ```JSON.stringify(Object.fromEntries(formData.entries()));``` – Kohver Mar 12 '20 at 15:20
  • 7
    @Kohver, better why? Does it remove duplicates? What kind of problems does it solve to make it better? – CervEd Feb 23 '21 at 15:09
  • 1
    Ah... stackoverflow do not disappoint, the answers keeps getting better the further I scroll down. LOL – codenamezero Jan 14 '22 at 16:43
  • 1
    Are we sure this works correctly? I tried it for FormData that had multiple values on the same key, and it only printed the last one in the JSON string. – mhively Mar 18 '22 at 22:48
28

Here's a way to do it in a more functional style, without the use of a library.

Array.from(formData.entries()).reduce((memo, [key, value]) => ({
  ...memo,
  [key]: value,
}), {});

Example:

document.getElementById('foobar').addEventListener('submit', (e) => {
  e.preventDefault();

  const formData = new FormData(e.target);
  const data = Array.from(formData.entries()).reduce((memo, [key, value]) => ({
    ...memo,
    [key]: value,
  }), {});
  document.getElementById('output').innerHTML = JSON.stringify(data);
});
<form id='foobar'>
  <input name='baz' />
  <input type='submit' />
</form>

<pre id='output'>Input some value and submit</pre>
dzuc
  • 706
  • 8
  • 11
  • 4
    I really like this answer but still do not handle multiple items. I posted a new answer based on this one to handle those cases. – CarlosH. Nov 11 '18 at 01:34
  • 1
    I advise to replace `pair` with `[key, value]` in order to exploit destructuring and improve readibility – Cristian Traìna Jan 31 '22 at 16:30
13

If you have multiple entries with the same name, for example if you use <SELECT multiple> or have multiple <INPUT type="checkbox"> with the same name, you need to take care of that and make an array of the value. Otherwise you only get the last selected value.

Here is the modern ES6-variant:

function formToJSON( elem ) {
  let output = {};
  new FormData( elem ).forEach(
    ( value, key ) => {
      // Check if property already exist
      if ( Object.prototype.hasOwnProperty.call( output, key ) ) {
        let current = output[ key ];
        if ( !Array.isArray( current ) ) {
          // If it's not an array, convert it to an array.
          current = output[ key ] = [ current ];
        }
        current.push( value ); // Add the new value to the array.
      } else {
        output[ key ] = value;
      }
    }
  );
  return JSON.stringify( output );
}

Slightly older code (but still not supported by IE11, since it doesn't support ForEach or entries on FormData)

function formToJSON( elem ) {
  var current, entries, item, key, output, value;
  output = {};
  entries = new FormData( elem ).entries();
  // Iterate over values, and assign to item.
  while ( item = entries.next().value )
    {
      // assign to variables to make the code more readable.
      key = item[0];
      value = item[1];
      // Check if key already exist
      if (Object.prototype.hasOwnProperty.call( output, key)) {
        current = output[ key ];
        if ( !Array.isArray( current ) ) {
          // If it's not an array, convert it to an array.
          current = output[ key ] = [ current ];
        }
        current.push( value ); // Add the new value to the array.
      } else {
        output[ key ] = value;
      }
    }
    return JSON.stringify( output );
  }
some
  • 46,247
  • 14
  • 74
  • 87
  • But when only 1 checked in checkbox, the value is still a single string, intead of being an array. – ArtixZ Nov 07 '21 at 19:34
  • That is correct. Since you can have multiple type of fields with the same name, I made the decision to set the value for first occurrence, and only convert it to an array if multiple values was found. I do not want to first scan the form to find field names that could result in arrays. – some Nov 09 '21 at 15:23
11

If you need support for serializing nested fields, similar to how PHP handles form fields, you can use the following function

function update(data, keys, value) {
  if (keys.length === 0) {
    // Leaf node
    return value;
  }

  let key = keys.shift();
  if (!key) {
    data = data || [];
    if (Array.isArray(data)) {
      key = data.length;
    }
  }

  // Try converting key to a numeric value
  let index = +key;
  if (!isNaN(index)) {
    // We have a numeric index, make data a numeric array
    // This will not work if this is a associative array 
    // with numeric keys
    data = data || [];
    key = index;
  }
  
  // If none of the above matched, we have an associative array
  data = data || {};

  let val = update(data[key], keys, value);
  data[key] = val;

  return data;
}

function serializeForm(form) {
  return Array.from((new FormData(form)).entries())
    .reduce((data, [field, value]) => {
      let [_, prefix, keys] = field.match(/^([^\[]+)((?:\[[^\]]*\])*)/);

      if (keys) {
        keys = Array.from(keys.matchAll(/\[([^\]]*)\]/g), m => m[1]);
        value = update(data[prefix], keys, value);
      }
      data[prefix] = value;
      return data;
    }, {});
}

document.getElementById('output').textContent = JSON.stringify(serializeForm(document.getElementById('form')), null, 2);
<form id="form">
  <input name="field1" value="Field 1">
  <input name="field2[]" value="Field 21">
  <input name="field2[]" value="Field 22">
  <input name="field3[a]" value="Field 3a">
  <input name="field3[b]" value="Field 3b">
  <input name="field3[c]" value="Field 3c">
  <input name="field4[x][a]" value="Field xa">
  <input name="field4[x][b]" value="Field xb">
  <input name="field4[x][c]" value="Field xc">
  <input name="field4[y][a]" value="Field ya">
  <input name="field5[z][0]" value="Field z0">
  <input name="field5[z][]" value="Field z1">
  <input name="field6.z" value="Field 6Z0">
  <input name="field6.z" value="Field 6Z1">
</form>

<h2>Output</h2>
<pre id="output">
</pre>
Joyce Babu
  • 18,005
  • 11
  • 60
  • 93
8

You can achieve this by using the FormData() object. This FormData object will be populated with the form's current keys/values using the name property of each element for the keys and their submitted value for the values. It will also encode file input content.

Example:

var myForm = document.getElementById('myForm');
myForm.addEventListener('submit', function(event)
{
    event.preventDefault();
    var formData = new FormData(myForm),
        result = {};

    for (var entry of formData.entries())
    {
        result[entry[0]] = entry[1];
    }
    result = JSON.stringify(result)
    console.log(result);

});
GiriB
  • 156
  • 5
  • This does not produce json – Liam Jan 03 '17 at 08:54
  • 1
    @Liam Have you tried this with form elements ? And let me know why it doesn't produce JSON object ? – GiriB Jan 03 '17 at 09:37
  • 1
    There is no such thing as a json object. Json is a string notation – Liam Jan 03 '17 at 10:13
  • 1
    @Liam After the object created they can use JSON.stringify(result). And I have edited my answer. Please check it. And withdraw the down vote. – GiriB Jan 03 '17 at 14:10
  • 1
    You can also make the for of statement more expressive if you're using ES6: `for (const [key, value] of formData.entries())` – Teddy Zetterlund Mar 22 '17 at 08:15
  • Warning to newcomers that copy/paste this: bear in mind that `for of` expression does not work in IE11 and other browsers that are not compatible with ES6. http://kangax.github.io/compat-table/es6/ – Tomás Sep 08 '17 at 11:19
  • you will run into issues if the query use an array form for the query key, for example something like this: [a][b][], you will not get all the checked values as you should – mr1031011 Jan 03 '18 at 11:43
7

This post is already a year old... but, I really, really like the ES6 @dzuc answer. However it is incomplete by not been able to handle multiple selects or checkboxes. This has already pointed and code solutions has been offered. I find them heavy and not optimized. So I wrote a 2 versions based on @dzuc to handle these cases:

  • For ASP style forms where multiple items name could just simple repeated.
let r=Array.from(fd).reduce(
  (o , [k,v]) => (
     (!o[k])
     ? {...o , [k] : v}
     : {...o , [k] : [...o[k] , v]}
   )
   ,{}
);
let obj=JSON.stringify(r);

One line Hotshot version:

Array.from(fd).reduce((o,[k,v])=>((!o[k])?{...o,[k]:v}:{...o,[k]:[...o[k],v]}),{});
  • For PHP style forms where the multiple item names must have a [] suffix.
let r=Array.from(fd).reduce(
  (o , [k,v]) => (
    (k.split('[').length>1)
    ? (k=k.split('[')[0]
      , (!o[k])
      ? {...o , [k] : [v]}
      : {...o , [k] : [...o[k] , v ]}
    )
    : {...o , [k] : v}
  )
  ,{}
);
let obj=JSON.stringify(r);

One line Hotshot version:

Array.from(fd).reduce((o,[k,v])=>((k.split('[').length>1)?(k=k.split('[')[0],(!o[k])?{...o,[k]:[v]}:{...o,[k]:[...o[k],v]}):{...o,[k]:v}),{});
  • Extension of PHP form that support multi-level arrays.

Since last time I wrote the previous second case, at work it came a case that the PHP form has checkboxes on multi-levels. I wrote a new case to support previous case and this one. I created a snippet to better showcase this case, the result show on the console for this demo, modify this to your need. Tried to optimize it the best I could without compromising performance, however, it compromise some human readability. It takes advantage that arrays are objects and variables pointing to arrays are kept as reference. No hotshot for this one, be my guest.

let nosubmit = (e) => {
  e.preventDefault();
  const f = Array.from(new FormData(e.target));
  const obj = f.reduce((o, [k, v]) => {
    let a = v,
      b, i,
      m = k.split('['),
      n = m[0],
      l = m.length;
    if (l > 1) {
      a = b = o[n] || [];
      for (i = 1; i < l; i++) {
        m[i] = (m[i].split(']')[0] || b.length) * 1;
        b = b[m[i]] = ((i + 1) == l) ? v : b[m[i]] || [];
      }
    }
    return { ...o, [n]: a };
  }, {});
  console.log(obj);
}
document.querySelector('#theform').addEventListener('submit', nosubmit, {capture: true});
<h1>Multilevel Form</h1>
<form action="#" method="POST" enctype="multipart/form-data" id="theform">
  <input type="hidden" name="_id" value="93242" />
  <input type="hidden" name="_fid" value="45c0ec96929bc0d39a904ab5c7af70ef" />
  <label>Select:
    <select name="uselect">
      <option value="A">A</option>
      <option value="B">B</option>
      <option value="C">C</option>
    </select>
  </label>
  <br /><br />
  <label>Checkboxes one level:<br/>
    <input name="c1[]" type="checkbox" checked value="1"/>v1 
    <input name="c1[]" type="checkbox" checked value="2"/>v2
    <input name="c1[]" type="checkbox" checked value="3"/>v3
  </label>
  <br /><br />
  <label>Checkboxes two levels:<br/>
    <input name="c2[0][]" type="checkbox" checked value="4"/>0 v4 
    <input name="c2[0][]" type="checkbox" checked value="5"/>0 v5
    <input name="c2[0][]" type="checkbox" checked value="6"/>0 v6
    <br/>
    <input name="c2[1][]" type="checkbox" checked value="7"/>1 v7 
    <input name="c2[1][]" type="checkbox" checked value="8"/>1 v8
    <input name="c2[1][]" type="checkbox" checked value="9"/>1 v9
  </label>
  <br /><br />
  <label>Radios:
    <input type="radio" name="uradio" value="yes">YES
    <input type="radio" name="uradio" checked value="no">NO
  </label>
  <br /><br />
  <input type="submit" value="Submit" />
</form>
CarlosH.
  • 661
  • 7
  • 12
  • 2
    `Array.from(fd).reduce((obj, [k, v]) => ({...obj, [k]: v}), {});` hotshot version es2018 – nackjicholson Feb 05 '19 at 00:45
  • 1
    @nackjicholson Yeap, you are right, omitting .entries() and the [k,v] element simplify the code. I will rewrite the code to include these improvements. However yours will still overwrite on repeated values. – CarlosH. Feb 06 '19 at 05:09
  • 10
    While I an appreciate the effort - code like this is absurd. Nobody wants to look at letters for variables and objects, this is not 1985. – Tom Stickel Nov 06 '19 at 21:12
  • 2
    Great solution, don't listen to the hater above. – Mike Jan 11 '21 at 14:38
6

Easy To Use Function

I Have Created A Function For This

function FormDataToJSON(FormElement){    
    var formData = new FormData(FormElement);
    var ConvertedJSON= {};
    for (const [key, value]  of formData.entries())
    {
        ConvertedJSON[key] = value;
    }

    return ConvertedJSON
}

Example Usage

var ReceivedJSON = FormDataToJSON(document.getElementById('FormId');)

In this code I have created empty JSON variable using for loop I have used keys from formData Object to JSON Keys in every Itration.

You Find This Code In My JS Library On GitHub Do Suggest Me If It Needs Improvement I Have Placed Code Here https://github.com/alijamal14/Utilities/blob/master/Utilities.js

Ali Jamal
  • 1,177
  • 12
  • 19
5

I've seen no mentions of FormData.getAll method so far.

Besides returning all the values associated with a given key from within a FormData object, it gets really simple using the Object.fromEntries method as specified by others here.

var formData = new FormData(document.forms[0])

var obj = Object.fromEntries(
  Array.from(formData.keys()).map(key => [
    key, formData.getAll(key).length > 1 ? 
      formData.getAll(key) : formData.get(key)
  ])
)

Snippet in action

var formData = new FormData(document.forms[0])

var obj = Object.fromEntries(Array.from(formData.keys()).map(key => [key, formData.getAll(key).length > 1 ? formData.getAll(key) : formData.get(key)]))

document.write(`<pre>${JSON.stringify(obj)}</pre>`)
<form action="#">
  <input name="name" value="Robinson" />
  <input name="items" value="Vin" />
  <input name="items" value="Fromage" />
  <select name="animals" multiple id="animals">
    <option value="tiger" selected>Tigre</option>
    <option value="turtle" selected>Tortue</option>
    <option value="monkey">Singe</option>
  </select>
</form>
OpSocket
  • 721
  • 10
  • 17
3

Even though the answer from @dzuc is already very good, you could use array destructuring (available in modern browsers or with Babel) to make it even a bit more elegant:

// original version from @dzuc
const data = Array.from(formData.entries())
  .reduce((memo, pair) => ({
    ...memo,
    [pair[0]: pair[1],
  }), {})

// with array destructuring
const data = Array.from(formData.entries())
  .reduce((memo,[key, value]) => ({
    ...memo,
    [key]: value,
  }), {})
Jeremias Erbs
  • 1,925
  • 2
  • 13
  • 7
3

If the following items meet your needs, you're in luck:

  1. You want to convert an array of arrays like [['key','value1'], ['key2','value2'] (like what FormData gives you) into a key->value object like {key1: 'value1', key2: 'value2'} and the convert it to a JSON string.
  2. You are targeting browsers/devices with the latest ES6 interpreter or are compiling with something like babel.
  3. You want the tiniest way to accomplish this.

Here is the code you'll need:

const data = new FormData(document.querySelector('form'));
const json = JSON.stringify(Array.from(data).reduce((o,[k,v])=>(o[k]=v,o),{}));

Hope this helps someone.

KyleFarris
  • 16,968
  • 5
  • 42
  • 40
3

I think this is the simplest way to get the result you want from a formData FormData object:

const jsonData = {};

for(const [key, value] of formData) {
    jsonData[key] = value;
}
Red Krow
  • 39
  • 1
2

If you are using lodash it can be done concisely with fromPairs

import {fromPairs} from 'lodash';

const object = fromPairs(Array.from(formData.entries()));
Erik van Velzen
  • 5,623
  • 3
  • 22
  • 20
2

You can try this

formDataToJSON($('#form_example'));

# Create a function to convert the serialize and convert the form data
# to JSON
# @param : $('#form_example');
# @return a JSON Stringify
function formDataToJSON(form) {
    let obj = {};
    let formData = form.serialize();
    let formArray = formData.split("&");

    for (inputData of formArray){
        let dataTmp = inputData.split('=');
        obj[dataTmp[0]] = dataTmp[1];
    }
    return JSON.stringify(obj);
}
Ivan Fretes
  • 608
  • 7
  • 10
2

Abusive one-liner!

Array.from(fd).reduce((obj, [k, v]) => ({...obj, [k]: v}), {});

Today I learned firefox has object spread support and array destructuring!

nackjicholson
  • 4,189
  • 3
  • 33
  • 35
2

Here is a function that turns a formData object into a JSON-string.

  • Works with multiple entries and nested arrays.
  • Works with both numbered and named input name arrays.

For example you can have the following form fields:

<select name="select[]" multiple></select>
<input name="check[a][0][]" type="checkbox" value="test"/>

Usage:

let json = form2json(formData);

The function:

function form2json(data) {
        
        let method = function (object,pair) {
            
            let keys = pair[0].replace(/\]/g,'').split('[');
            let key = keys[0];
            let value = pair[1];
            
            if (keys.length > 1) {
                
                let i,x,segment;
                let last = value;
                let type = isNaN(keys[1]) ? {} : [];
                
                value = segment = object[key] || type;
                
                for (i = 1; i < keys.length; i++) {
                    
                    x = keys[i];
                    
                    if (i == keys.length-1) {
                        if (Array.isArray(segment)) {
                            segment.push(last);
                        } else {
                            segment[x] = last;
                        }
                    } else if (segment[x] == undefined) {
                        segment[x] = isNaN(keys[i+1]) ? {} : [];
                    }
                    
                    segment = segment[x];
                    
                }
                
            }
            
            object[key] = value;
            
            return object;
            
        }
        
        let object = Array.from(data).reduce(method,{});
        
        return JSON.stringify(object);
        
    }
frankichiro
  • 31
  • 1
  • 3
  • This, for me, seems to be the best answer and covers the variety of possible input names. Thanks for sharing. (Just add `function` before the first statement and you are golden.) – z-x Mar 22 '22 at 12:27
  • `function` added, thanks! – frankichiro Mar 23 '22 at 14:16
1

Making use of toJSON as described in JSON.stringify()

If the value has a toJSON() method, it's responsible to define what data will be serialized.

Here is a little hack.

var fd = new FormData(document.forms[0]);

fd.toJSON = function() {
  const o = {};
  this.forEach((v, k) => {
    v = this.getAll(k);
    o[k] = v.length == 1 ? v[0] : (v.length >= 1 ? v : null);
  });
  return o;
};

document.write(`<pre>${JSON.stringify(fd)}</pre>`)
<form action="#">
  <input name="name" value="Robinson" />
  <input name="items" value="Vin" />
  <input name="items" value="Fromage" />
  <select name="animals" multiple id="animals">
    <option value="tiger" selected>Tigre</option>
    <option value="turtle" selected>Tortue</option>
    <option value="monkey">Singe</option>
  </select>
</form>
Umair Khan
  • 1,566
  • 16
  • 32
1

This solved my issue and this is for an Object

const formDataObject = (formData) => {

for (const key in formData) {
    if (formData[key].startsWith('{') || formData[key].startsWith('[')) {
        try {
            formData[key] = JSON.parse(formData[key]);
            console.log("key is :", key, "form data is :", formData[key]);

        } catch (error) {
            console.log("error :", key);
        }
    }
}

console.log("object", formData)
}
Roman Pokrovskij
  • 8,849
  • 17
  • 82
  • 136
1

Another approach that works with select multiple or inputs with same name attribute:

function form_to_json() {
  const form_data = new FormData(document.querySelector('form'))
  const uniqueKeys = [...new Set(form_data.keys())]  
  const obj = {}
  uniqueKeys.forEach((value, key) => {
    obj[value] = (form_data.getAll(value).length > 1) ? form_data.getAll(value) : form_data.get(value)
  })
  const json = JSON.stringify(obj)
  alert(json)
}
<form>
  <input type="text" name="name" value="Cesar"></br>
  <select name="cars" id="cars" multiple>
    <option value="volvo" selected>Volvo</option>
    <option value="saab" selected>Saab</option>
  </select>
  <input type="button" onclick="form_to_json()" value="Ok">
</form>
Cesar Morillas
  • 327
  • 2
  • 6
0

Worked for me

                var myForm = document.getElementById("form");
                var formData = new FormData(myForm),
                obj = {};
                for (var entry of formData.entries()){
                    obj[entry[0]] = entry[1];
                }
                console.log(obj);
0

In my case form Data was data , fire base was expecting an object but data contains object as well as all other stuffs so i tried data.value it worked!!!

0

I am arriving late here. However, I made a simple method that checks for the input type="checkbox"

var formData = new FormData($form.get(0));
        var objectData = {};
        formData.forEach(function (value, key) {
            var updatedValue = value;
            if ($('input[name="' + key + '"]').attr("type") === "checkbox" && $('input[name="' + key + '"]').is(":checked")) {
                updatedValue = true; // we don't set false due to it is by default on HTML
            }
            objectData[key] = updatedValue;
        });
var jsonData = JSON.stringify(objectData);

I hope this helps somebody else.

acido
  • 508
  • 1
  • 5
  • 21
0

if you want the json string :

var jsonStr =  JSON.stringify($('#formId').serializeObject());

if you want a json Object

var jsonObj =  JSON.parse(JSON.stringify($('#formId').serializeObject()));
Bilal
  • 1,114
  • 11
  • 14
0

I know its late, but here's the solution;

new URLSearchParams(new FormData(formElement)).toString()

Now, this can be sent as the body. Sadly, its not JSON.

Akshay K Nair
  • 615
  • 9
  • 22
0

Years later in vanillaJs (es6)

let body = new FormData()

body.set('key1', 'value AA')

body.set('key2', 'value BB')

let data = [...body.keys()].reduce( (acc, key, idx) => {
    acc[key] = body.get(key)
    return acc
} , {} )

console.log(JSON.stringify(data)) // {key1: 'value AA', key2: 'value BB'}

Wolfgang Leon
  • 607
  • 9
  • 20
0

Here's a way that includes a simple way to handle multiple values. If a key ends with [], it combines the values into an array (like in the old php convention), and drops the [] from the key:

function formDataToJson(f) {
  return Object.fromEntries(Array.from(f.keys(), k =>
    k.endsWith('[]') ? [k.slice(0, -2), f.getAll(k)] : [k, f.get(k)]));
}

For example, if you have:

const f = new FormData();
f.append("a", "1");
f.append("a", "2");
f.append("b[]", "3");
f.append("b[]", "4");
formDataToJson(f)  // --> produces {a: "1", b: ["3","4"]}
DS.
  • 20,509
  • 5
  • 45
  • 53
-2

This works for me. Click here to see the details code

let formToJson = function(){
    let form = new FormData($("form#formData")[0]);
    //console.log(form);
    let jsonData = Object.fromEntries(form.entries());
    //console.log(jsonData);
    $("#jsonData").html(JSON.stringify(jsonData));
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
    <title>Document</title>
</head>
<body>
    <div class="">
        <form action="#" method="post" id="formData">
            <input type="text" name="fName" id="fName" value="Mad"><br>
            <input type="text" name="lName" id="lName" value="Coder"><br>
            <input type="button" onclick="formToJson()" value="Boom Yeah">
        </form>
    </div>
    <div id="jsonData">
    </div>
</body>
</html>