FormData API: Handle Forms like Boss ?
Handling Forms has always been confusing as there are many ways to do so. Let's take a look at the cool features of FormData API to handle Forms.
Forms are very crucial to Web Apps and SPAs. And handling them was always confusing as there are so many different ways to handle it.
Today we will take a look at the cool features of FormData API to handle Forms.
Like the name suggests, FormData API will give you fine-grained control over the form elements and the values.
This API is really helpful as these days we generally make WebApps or SPAs where we don't send data to server by form submit but as API calls and FormData will easily help you craft form requests for AJAX or fetch
In simple words, FormData is a form in terms of Object. Though it can be created from an HTML Form as well.
Lets see two examples:
In-Memory
const form = new FormData();
form.append('name', 'Time to Hack');
form.append('url', 'https://time2hack.com');
console.log(form) // FormData {}
From HTML
<form id="profileForm" name="profileForm">
<input type="text" id="name" name="name" placeholder="Name" />
<input type="text" id="url" name="url" placeholder="URL" />
<input type="file" id="photo" name="photo" placeholder="Photo" />
</form>
const form = new FormData(document.querySelector('#profileForm'));
// or
const otherForm = new FormData(document.forms['profileForm']);
console.log(form, otherForm) // FormData {}, FormData {}
Let's take a look on what FormData object contains under the hood:
(this list has been taken from https://developer.mozilla.org/en-US/docs/Web/API/FormData)
Method | Description |
---|---|
FormData.append() |
Appends a new value onto an existing key inside a FormData object, or adds the key if it does not already exist. |
FormData.delete() |
Deletes a key/value pair from a FormData object. |
FormData.entries() |
Returns an iterator allowing to go through all key/value pairs contained in this object. |
FormData.get() |
Returns the first value associated with a given key from within a FormData object. |
FormData.getAll() |
Returns an array of all the values associated with a given key from within a FormData . |
FormData.has() |
Returns a boolean stating whether a FormData object contains a certain key/value pair. |
FormData.keys() |
Returns an iterator allowing to go through all keys of the key/value pairs contained in this object. |
FormData.set() |
Sets a new value for an existing key inside a FormData object, or adds the key/value if it does not already exist. |
FormData.values() |
Returns an iterator allowing to go through all values of the key/value pairs contained in this object. |
Now let's see what data is inside the FormData. For this I created a small function to take the form keys and values and put them in an object:
const objectFromFormData = formData => {
const values = {};
for (let [key, value] of formData.entries()) {
if (values[key]) {
if ( ! (values[key] instanceof Array) ) {
values[key] = new Array(values[key]);
}
values[key].push(value);
} else {
values[key] = value;
}
}
return values;
}
Now if you notice in above example, you will see that there is no country key. It is because in above example, I have not added name
attribute to country input.
So all form fields should have the name attribute to be counted inside the FormData when instantiating from HTML Form.
We can add that field explicitly to the Form data and then use it with following code:
const form = new FormData(document.forms['profileForm']);
form.set('country', document.querySelector('#country').value);
And now this form data can be used to send as body in AJAX request like we are doing here:
Or it can be used with above stated function objectFromFormData
to send this data to any JSON store like Firebase or JSON payload to AJAX request.
Checkout the Chrome extension to debug Form Data:
Conclusion
As you saw FormData will ease your Form Handling troubles in multiple ways; at least, you can get rid of hidden form with hidden inputs ?.
What do you think about it?
Let me know through comments ? or on Twitter at @heypankaj_ and/or @time2hack
If you find this article helpful, please share it with others ?
Subscribe to the blog to receive new posts right to your inbox.