published: 15 May 2022
2 min read
Working with FormData API in JavaScript
The FormData
interface provides a simple way to store key-value pairs corresponding to HTML form fields and their values. It works in all modern browsers and Internet Explorer 10+.
As the name suggests, the FormData
interface is designed to hold form data, allowing us to build an object representing an HTML form in JavaScript.
It is commonly used when you need to asynchronously send form data to a RESTful API end-point. For instance, uploading a single or multiple files using the Fetch()
API, XMLHttpRequest
interface, or Axios.
Creating an object
To create an object of the FormData
interface, you can call its constructor with the new
operator as shown below:
const fd = new FormData();
In the above code, the fd
variable refers to an instance of FormData
. You can now call methods on the object to add, remove, or update key-value pairs presenting form fields.
Methods
The FormData
interface provides the following methods:
append()
- Append a new key-value pair to the object. If the key already exists, the value is appended to the original value of that key.delete()
- Delete a key-value pair from the object.entries()
- Returns an iterator object that allows you to loop through all key-value pairs added to this object.get()
- Returns the first value associated with the given key.getAll()
- Returns an array of all the values associated with the given key.has()
- Returns a boolean value indicating whether the given key exists or not inside this object.keys()
- Returns an iterator object that can be used to list the available keys in this object.set()
- Sets a new value for an existing key. It is useful to replace an existing key value.values()
- Returns an iterator object that can be used to list all available values in this object.
How to use it?
Let us say we are working on a web application that enables users to upload a profile picture. We want to create an HTML form allowing users to upload an image with the name and the email address.
Our HTML markup looks like the following:
<form id='profile-form'>
<input type='text' id='name' name='name' placeholder='Name'>
<input type='email' id='email' name='email' placeholder='Email Address'>
<input type='file' id='avatar' name='avatar'>
<button>Submit</button>
</form>
Now attach an event listener to the form that will be called when the form is submitted:
const form = document.querySelector('#profile-form');
// Attach event handler to form
form.addEventListener('submit', (e) => {
// Disable default submission
e.preventDefault();
// TODO: submit the form manually
});
The above code adds a submit
event handler to the form. Inside the event handler function, we disable the default action in favor of manual form submission using the FormData
interface.
Next, create a new instance of FormData
and append each element into it:
const name = document.querySelector('#name');
const email = document.querySelector('#email');
const avatar = document.querySelector('#avatar');
// Create a new FormData object
const fd = new FormData();
fd.append('name', name.value);
fd.append('email', email.value);
fd.append('avatar', avatar.files[0]);
Finally, post the FormData
object with the fetch()
API and logs the response on the console:
fetch('/update-profile', {
method: 'POST',
mode: 'no-cors',
body: fd
}).then(res => res.json())
.then(json => console.log(json))
.catch(err => console.error(err));
Here is the complete example code:
const form = document.querySelector('#profile-form');
// Attach event handler to form
form.addEventListener('submit', (e) => {
// Disable default submission
e.preventDefault();
// Submit form manually
const name = document.querySelector('#name');
const email = document.querySelector('#email');
const avatar = document.querySelector('#avatar');
// Create a new FormData object
const fd = new FormData();
fd.append('name', name.value);
fd.append('email', email.value);
fd.append('avatar', avatar.files[0]);
// send 'POST' request
fetch('/update-profile', {
method: 'POST',
mode: 'no-cors',
body: fd
}).then(res => res.json())
.then(json => console.log(json))
.catch(err => console.error(err));
});
To upload multiple files with the FormData
interface, take a look at this article.
Passing form
reference
Note that the FormData
constructor can take a reference to an HTML <form>
element as an argument. When provided, the 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 also includes the file input content.
So instead of manually calling append()
method for each input element, you can just do the following:
const fd = new FormData(e.currentTarget);
The e.currentTarget
property always refers to the element whose event listener triggered the event. In our case, it is the <form>
element.
Overwriting a key
Another important thing to remember is that the append()
method does not overwrite a key if it already exists. It is by design to allow multiple values for a single key:
const fd = new FormData();
fd.append('size', 'L');
fd.append('size', 'XL');
console.log(fd.getAll('size')); // ['L', 'XL']
To overwrite a key, use the set()
method instead:
// ...
fd.set('size', 'M');
console.log(fd.getAll('size')); // ['M']
Browser compatibility
Except for the append()
method that works across all browsers, all other methods are only available in modern browsers.
Are we missing something? Help us improve this article. Reach out to us.
Working with FormData API in JavaScript
The FormData
interface provides a simple way to store key-value pairs corresponding to HTML form fields and their values. It works in all modern browsers and Internet Explorer 10+.
As the name suggests, the FormData
interface is designed to hold form data, allowing us to build an object representing an HTML form in JavaScript.
It is commonly used when you need to asynchronously send form data to a RESTful API end-point. For instance, uploading a single or multiple files using the Fetch()
API, XMLHttpRequest
interface, or Axios.
Creating an object
To create an object of the FormData
interface, you can call its constructor with the new
operator as shown below:
const fd = new FormData();
In the above code, the fd
variable refers to an instance of FormData
. You can now call methods on the object to add, remove, or update key-value pairs presenting form fields.
Methods
The FormData
interface provides the following methods:
append()
- Append a new key-value pair to the object. If the key already exists, the value is appended to the original value of that key.delete()
- Delete a key-value pair from the object.entries()
- Returns an iterator object that allows you to loop through all key-value pairs added to this object.get()
- Returns the first value associated with the given key.getAll()
- Returns an array of all the values associated with the given key.has()
- Returns a boolean value indicating whether the given key exists or not inside this object.keys()
- Returns an iterator object that can be used to list the available keys in this object.set()
- Sets a new value for an existing key. It is useful to replace an existing key value.values()
- Returns an iterator object that can be used to list all available values in this object.
How to use it?
Let us say we are working on a web application that enables users to upload a profile picture. We want to create an HTML form allowing users to upload an image with the name and the email address.
Our HTML markup looks like the following:
<form id='profile-form'>
<input type='text' id='name' name='name' placeholder='Name'>
<input type='email' id='email' name='email' placeholder='Email Address'>
<input type='file' id='avatar' name='avatar'>
<button>Submit</button>
</form>
Now attach an event listener to the form that will be called when the form is submitted:
const form = document.querySelector('#profile-form');
// Attach event handler to form
form.addEventListener('submit', (e) => {
// Disable default submission
e.preventDefault();
// TODO: submit the form manually
});
The above code adds a submit
event handler to the form. Inside the event handler function, we disable the default action in favor of manual form submission using the FormData
interface.
Next, create a new instance of FormData
and append each element into it:
const name = document.querySelector('#name');
const email = document.querySelector('#email');
const avatar = document.querySelector('#avatar');
// Create a new FormData object
const fd = new FormData();
fd.append('name', name.value);
fd.append('email', email.value);
fd.append('avatar', avatar.files[0]);
Finally, post the FormData
object with the fetch()
API and logs the response on the console:
fetch('/update-profile', {
method: 'POST',
mode: 'no-cors',
body: fd
}).then(res => res.json())
.then(json => console.log(json))
.catch(err => console.error(err));
Here is the complete example code:
const form = document.querySelector('#profile-form');
// Attach event handler to form
form.addEventListener('submit', (e) => {
// Disable default submission
e.preventDefault();
// Submit form manually
const name = document.querySelector('#name');
const email = document.querySelector('#email');
const avatar = document.querySelector('#avatar');
// Create a new FormData object
const fd = new FormData();
fd.append('name', name.value);
fd.append('email', email.value);
fd.append('avatar', avatar.files[0]);
// send 'POST' request
fetch('/update-profile', {
method: 'POST',
mode: 'no-cors',
body: fd
}).then(res => res.json())
.then(json => console.log(json))
.catch(err => console.error(err));
});
To upload multiple files with the FormData
interface, take a look at this article.
Passing form
reference
Note that the FormData
constructor can take a reference to an HTML <form>
element as an argument. When provided, the 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 also includes the file input content.
So instead of manually calling append()
method for each input element, you can just do the following:
const fd = new FormData(e.currentTarget);
The e.currentTarget
property always refers to the element whose event listener triggered the event. In our case, it is the <form>
element.
Overwriting a key
Another important thing to remember is that the append()
method does not overwrite a key if it already exists. It is by design to allow multiple values for a single key:
const fd = new FormData();
fd.append('size', 'L');
fd.append('size', 'XL');
console.log(fd.getAll('size')); // ['L', 'XL']
To overwrite a key, use the set()
method instead:
// ...
fd.set('size', 'M');
console.log(fd.getAll('size')); // ['M']
Browser compatibility
Except for the append()
method that works across all browsers, all other methods are only available in modern browsers.
Are you looking for other code tips?
JS Nooby
Javascript connoisseur