javascriptphpcodeigniterform-datafilelist

Send FileList in FormData in javascrirpt


I am trying to send a bunch of images using FormData but of course, I cannot send FileList and I was unsuccessful in figuring out a way to send these files. I have already tried to find answers on my own but most of them suggest appending each file.

for (let i = 0 ; i < images.length ; i++) {
    formData.append("images[]", images[i]);
}

But it ends up with only the last file inside formData, for some reason previous files are being replaced by the next one in line.

I have also tried to convert FileList to an array, which works but I don't know how I could separate these files, right now every file is inside one key as a string.

0: "[{\"lastModified\":1606255989000,\"lastModifiedDate\":\"undefined\",\"name\":\"logo.png\",\"size\":54438,\"type\":\"image/png\"},{\"lastModified\":1606255979000,\"lastModifiedDate\":\"undefined\",\"name\":\"logo1.png\",\"size\":58023,\"type\":\"image/png\"},{\"lastModified\":1606252752000,\"lastModifiedDate\":\"undefined\",\"name\":\"logo2.png\",\"size\":28147,\"type\":\"image/png\"},{\"lastModified\":1606255121000,\"lastModifiedDate\":\"undefined\",\"name\":\"logo3.png\",\"size\":18260,\"type\":\"image/png\"}]"

I could just convert it to string and cut it to their own keys using } as and end of each entry. I don't want to do this, even with my little experience I know it's not a good way to go about it.

As of this moment, my javascript code looks like this.

 File.prototype.toObject = function () {
  return Object({
    lastModified: parseInt(this.lastModified),
    lastModifiedDate: String(this.lastModifiedDate),
    name: String(this.name),
    size: parseInt(this.size),
    type: String(this.type)
    })
  }

  FileList.prototype.toArray = function () {
    return Array.from(this).map(function (file) {
      return file.toObject()
    })
  }

  let files = document.getElementById('files').files

  let filesArray = files.toArray();

  let formData = new FormData();

  formData.append('images[]', JSON.stringify(filesArray));

I then send this data like this

fetch('<?=env('app.baseURL')?>/admin/gallery', {
      method: 'POST',
      processData: false,
      headers: {
          'X-Requested-With': 'XMLHttpRequest'
      },
      body: formData,
      data: formData,
      }).then(function (response) {...rest of the code...})

After sending this data, which is received without any problems I want to save these files, but I cannot without first separating them. I am using PHP for the back-end.

I don't have much experience with javascript so I might be missing something obvious, any help is appreciated.


Solution

  • In your for loop you could use dynamic name for your formData appends. For example:

    formData.append(`image-${i}`, images[i])
    

    Or in case you want to push your images to a single key value pair in your formData, like in your example, you should use the getAll() method to retrieve your images.

    formData.getAll('images[]')