Using FormData to Upload Multiple Images
Recently, I’ve been working on an app which allows a user to upload a gallery of photos and narrow down which photo(s) are their favorite from that gallery. I’ve been using a React frontend and a Rails API backend.
As I was building my react, Upload
component, I needed to find a way to send the user’s images-all at once- to my Rails backend. At first, I tried to create an object which contained my array of images. ie:
const gallery = { images: imagesFromInput }
However, when I tried to attach the object to the body of my fetch request to POST the gallery to my rails backend, the data was lost.
After digging around, I discovered that I needed to use the FormData
object with my fetch request. From the docs:
The
FormData
interface provides a way to easily construct a set of key/value pairs representing form fields and their values, which can then be easily sent using theXMLHttpRequest.send()
method. It uses the same format a form would use if the encoding type were set to"multipart/form-data"
.
First, I needed to create a FormData object:
const galleryData = new FormData()
In order to add a key/value pair to the object, you use the append
method:
FormData.append('key', 'value')
At first, I tried to simply append my array to the FormData object like so:
galleryData.append('images', imageArrayFromInput)
However, the array structure was lost in translation and the files were unusable to my backend.
After poking around for hours, banging my head against the wall, and trying multiple attempts at getting the array to append to my FormData
object, I finally discovered the proper way to append my image array to the object! In order for the FormData to send the value as a readable array without losing your data, you must simply add []
to the end of your key
in the append
method and loop through your array in order to push each image onto the array:
FormData.append('key[]', array[0])
FormData.append('key[]', array[1])
etc...
My final code for structuring my FormData object looks something like this where files
is my state object which contains the user’s images from the form:
const galleryData = new FormData()
for (let i = 0; i < files.length; i++) {
galleryData.append('images[]', file[i])
}