- How to serialize form data with vanilla JS
- The FormData object
- Looping through FormData
- Adding, updating, and removing items from a FormData object
- How to convert a FormData object into an object or query string
- Serializing HTML Form Data with JavaScript
- Table of Contents
- 1. Listen to the Form’s input Event
- 2. Construct FormData
- 3. Serialize the Form Data with URLSearchParams
- 4. Assemble the Final URL for the Form
- Final Code
- Thanks for reading!
- How to Serialize Form Data with Javascript
- Serialiazing Form Data for a GET Request
- Serialiazing Form Data for a POST Request
- Useful Resources
How to serialize form data with vanilla JS
Historically, getting data from a form into a format you could send to an API was a bit difficult, but modern techniques make it a lot easier.
The FormData object
The FormData object provides an easy way to serialize form fields into key/value pairs.
You can use the new FormData() constructor to create a new FormData object, passing in the form to serialize as an argument. Form fields must have a name attribute to be included object. Otherwise, they’re skipped. The id property doesn’t count.
For example, if you have a form that looked like this…
form id="post"> label for="title">Titlelabel> input type="text" name="title" id="title" value="Go to the beach"> label for="body">Bodylabel> textarea id="body" name="body">Soak up the sun and swim in the ocean.textarea> input type="hidden" name="userId" value="1"> button>Submitbutton> form>
You would serialize it like this…
// Get the form let form = document.querySelector('#post'); // Get all field data from the form // returns a FormData object let data = new FormData(form);
Looping through FormData
The FormData object is an iterable, which means you can loop through it using a for. of loop (you’ll notice that a trend with many of the newer JS methods).
Each entry in the loop is an array of key/value pairs.
// logs. // ["title", "Go to the beach"] // ["body", "Soak up the sun and swim in the ocean."] // ["userId", "1"] for (let entry of data) console.log(entry); >
Because the entry values are arrays, you can also use array destructuring to assign the key and value to their own variables within the for. of loop.
// logs "title", "Go to the beach", etc. for (let [key, value] of data) console.log(key); console.log(value); >
Adding, updating, and removing items from a FormData object
The FormData object has several methods that you can use to add, remove, and update items.
Use the FormData.set() method to replace an existing entry, or add a new one if an entry with that key doesn’t exist. Pass in the key and value as arguments.
// Updates the userId field with a new value data.set('userId', '3'); // Creates a new key, "date", with a value of "4" data.set('date', 'July 4');
Use the FormData.append() method to add a new entry, passing in the key and value as arguments. If an item with that key already exists, another one is added and the existing one is unaffected.
// Add a second "body" key to the data FormData object data.append('body', 'Eat ice cream');
Use the FormData.delete() method to delete an entry, passing in the key as an argument. If more than one item with that key exist, all of them are deleted.
// Delete items with the "body" key data.delete('body');
How to convert a FormData object into an object or query string
The FormData object can be submitted as-is to some endpoints with a content-type header of multipart/form-data , not not all APIs support that.
To serialize a FormData object into a query string, pass it into the new URLSearchParams() constructor. This will create a URLSearchParams object of encoded query string values.
Then, call the URLSearchParams.toString() method on it to convert it into a query string.
// Get the form let form = document.querySelector('#post'); // Get all field data from the form let data = new FormData(form); // Convert to a query string let queryString = new URLSearchParams(data).toString();
To serialize a FormData object into a plain object, we need to loop through each entry with a for. of loop and add it to an object.
let obj = <>; for (let [key, value] of data) obj[key] = value; >
But, if there’s more one form field with the same name, the original value will get overwritten. To account for this, we need to check if the key already exists in the obj . If it does, we want to convert it to an array and Array.push() the new value into it.
let obj = <>; for (let [key, value] of data) if (obj[key] !== undefined) if (!Array.isArray(obj[key])) obj[key] = [obj[key]]; > obj[key].push(value); > else obj[key] = value; > >
Here’s a helper function you can use to convert a FormData object into a plain object. Pass in the FormData object as an argument.
function serialize (data) let obj = <>; for (let [key, value] of data) if (obj[key] !== undefined) if (!Array.isArray(obj[key])) obj[key] = [obj[key]]; > obj[key].push(value); > else obj[key] = value; > > return obj; >
And here’s how you would use it.
// Get the form let form = document.querySelector('#post'); // Get all field data from the form let data = new FormData(form); // Convert to an object let formObj = serialize(data);
Hate the complexity of modern front‑end web development? I send out a short email each weekday on how to build a simpler, more resilient web. Join over 14k others.
Made with ❤️ in Massachusetts. Unless otherwise noted, all code is free to use under the MIT License. I also very irregularly share non-coding thoughts.
Serializing HTML Form Data with JavaScript
You typically don’t need to worry about serializing HTML form data yourself. If a form has a submit button, then it will serialize its data automatically when a user submits it. Specifically, if the form is of type GET , it will redirect the user to the target URL (as determined by the form’s method attribute) with its data serialized as a query string. For example, consider this form:
form action="/endpoint" method="get"> label>Titleinput name="title" type="text"> label>Descriptioninput name="description" type="text"> button type="submit">Submitbutton> form>
It has two inputs with explicit name s: a title and a description . These name attributes are used as the names of the query string parameters when serializing the form’s data in the URL. So when a user submits this form, the page will redirect them to /endpoint?title=abc&description=123 , where abc and 123 here are just placeholders for the user-supplied values.
That’s great! HTML forms are amazing and give us a lot of functionality out of the box for free. But what if you do need to serialize the form data yourself? While this use case is admittedly rare, it does come up now and then. For example, you might want to show a preview of the final URL in real time as a user fills out your form. My Fluid Type Scale Calculator app does this to allow for simple link sharing—a user can easily copy the URL and send it to someone else without ever needing to submit the form.
Thankfully, serializing form data with JavaScript is easy—the code ends up being just a handful of lines. We just need to use the following object constructors:
Here’s a demo of what we’ll be building:
Table of Contents
1. Listen to the Form’s input Event
First, we’ll add an event listener for the input event to our form (note: in React, this is confusingly called the change event). This event listener will be called whenever the input event bubbles up from one of the form’s children, such as one of the inputs:
document.querySelector('form').addEventListener('input', (e) => const form = e.currentTarget; >);
Here, I’m reading e.currentTarget to get a reference to the form element, which we’re going to use shortly. Alternatively, you could assign a ref to the form before registering the event listener and just reference that variable instead:
const form = document.querySelector('form'); form.addEventListener('input', (e) => >);
2. Construct FormData
Inside our event listener, we’ll now construct a FormData object, which represents all of the input-value pairs for the form’s named fields. In our example, those fields are title and description .
const data = new FormData(form);
At this point, you may be tempted to parse each piece of data using the FormData.get method and serialize the form data by hand:
const title = data.get('title'); const description = data.get('description'); const query = `?title=$title>&description=$description>`;
However, there’s an easier way!
3. Serialize the Form Data with URLSearchParams
Next, we’ll use the URLSearchParams constructor to convert this object into a query string:
const data = new FormData(form); const queryString = new URLSearchParams(data).toString();
The great thing about URLSearchParams is that it already encodes special characters for us to prevent malformed URLs. For example, spaces will be encoded as %2C .
4. Assemble the Final URL for the Form
In the final step, we’ll use the URL constructor to assemble the URL for the form. The URL constructor accepts two arguments: the target path and the base URL. In our case, we’ll read the target path directly off of the form itself by accessing form.action and join it with the current location:
const url = new URL(form.action, window.location.href);
If the form endpoint’s protocol and origin differ from those of the base URL, then the first URL will take priority, so new URL(‘https://my.endpoint’, ‘https://my.form.page’) will just become https://my.endpoint .
Now, we’ll take the query string we assembled in the previous step and assign it to url.search :
Finally, we’ll convert that URL object to a string:
const formUrl = url.toString();
At this point, you can do whatever you want with the URL. For example, you might render it in an element:
const output = document.querySelector('output'); output.innerText = formUrl;
Final Code
All it takes is just a few lines of JavaScript to serialize an HTML form into a well-formatted URL. Here’s the final code from this tutorial:
const output = document.querySelector('output'); const form = document.querySelector('form'); form.addEventListener('input', (e) => const data = new FormData(form); const url = new URL(form.action, window.location.href); url.search = new URLSearchParams(data).toString(); // do whatever you want with the URL >);
Thanks for reading!
© Aleksandr Hovhannisyan, 2019–Present
How to Serialize Form Data with Javascript
Serialization of form data means to create a string of URL encoded name-value pairs of the form data parameters. Each pair is separated by a & character.
user=aks&post=12&sort=desc&contains=U+A
While implementing AJAX requests, libraries such as jQuery handle serialization of form data by themselves. But when trying to do this with vanilla Javascript (using XHR), it becomes your responsibility to serialize the form data to be sent.
You can form a query string of encoded key/value pairs by appending parameters to a string, but somehow doing that seems like a waste of time. There are external libraries that do this — but using libraries for such small purposes is not very right.
The good news is that modern browsers have methods that can serialize form data natively. This happens with the URLSearchParams and FormData objects.
Serialiazing Form Data for a GET Request
For a GET request, you can get a url encoded query string by using the URLSearchParams object.
Multiple values for a single parameter can also be handled.
// new URLSearchParams object var search_params = new URLSearchParams(); // append parameters search_params.append('post', '12'); search_params.append('post', '15'); search_params.append('sort', 'desc'); search_params.append('contains', 'U A'); // query string var query_string = search_params.toString(); // will output "post=12&post=15&sort=desc&contains=U+A" console.log(query_string); // send form data in AJAX request var xhr = new XMLHttpRequest(); xhr.open('GET', 'ajax.php'); xhr.send(query_string);
Serialiazing Form Data for a POST Request
- Simple POST request (no files uploaded) When no files are being uploaded, the Content-Type header of the POST request is usually application/x-www-form-urlencoded . The query string in this case is just like the query string of a GET request — each name-value pair separated by a & character. So you can use the URLSearchParams object in this case also (described above).
- POST request with files uploaded When files are being uploaded, the Content-Type header of the POST request is multipart/form-data . In this case form data is separated by a specific boundary. The URLSearchParams object won’t work in this case. You will need the FormData object here.
// new FormData object var formdata = new FormData(); // textual parameters formdata.append('post', '12'); formdata.append('type', 'normal'); // file to be uploaded // comes from a file input formdata.append('file', document.querySelector("#file").files[0]); // send form data in AJAX request var xhr = new XMLHttpRequest(); xhr.open('POST', 'ajax.php'); xhr.send(formdata);