pqina / svelte-filepond

🔌 A handy FilePond adapter component for Svelte
MIT License
247 stars 10 forks source link

allowMultiple only gives first unique file id on form submission #19

Closed RossAddinall closed 1 year ago

RossAddinall commented 1 year ago

I am using the Svelte filepond component and wish to allow multiple files to be uploaded.

I have created the /process endpoint and a unique id is returned for each file.

On form submission, however, I don't get an array of unique file id's I only get a single unique file id, the id for the first file that I dropped.

I have looked on StackOverflow and can find nothing and I have scoured the documentation, but can find nothing. The closest I can get is this issue, which seems to hint at having to specify an array syntax.

Please could you point me at the correct part of the documentation or give me some hints, if this needs specifically documenting, then I will submit a PR for the documentation once I have it working.

Many thanks in advance for your help.

This is what I have in my code:

<FilePond 
    allowMultiple={true}
    name={key}
    labelIdle='Drag & drop your files or <span class="filepond--label-action">click to browse</span>'
    maxFiles={100}
    allowReorder={true}
    allowReplace={false}
    allowRemove={true}
    allowProcess={true}
    allowPaste={true}
    stylePanelLayout={'compact'}
    beforeDropFile={beforeDropFile}
    beforeAddFile={beforeAddFile}
    onupdatefiles={onUpdateFiles}
    server={{
      url: baseURL + "/api/file_upload",
      process: '/process',
      revert: '/revert',
      restore: null,
      load: null,
      fetch: null
    }}
  />

where key is the name of the form field.

I have tried with:

  name={key + '[]'}

but this makes no difference.

rikschennink commented 1 year ago

The server process method should return a file id which is then stored in a hidden input.

I'd start by inspecting the DOM to check if it contains all the file ids.

RossAddinall commented 1 year ago

@rikschennink Thanks for your quick response.

Yes, I can see the id's appearing in the DOM, as I drag and drop the files, they upload and the server returns a unique id and so after three files I have:

<fieldset class="filepond--data">
  <input type="hidden" name="VERILOG_FILES" value="86e89ee8-02a7-4f2f-acd5-d1d32624d499">
  <input type="hidden" name="VERILOG_FILES" value="5f6c2b2c-137e-4633-bd81-00176f9d8dd1">
  <input type="hidden" name="VERILOG_FILES" value="9a82054b-430a-4130-9075-138681028598">
</fieldset>

... Ahhh, OK, I've found the error.

I was processing the formData with this function:

const handleSubmit = (event) => {
    event.preventDefault();
    const formData = new FormData(event.target);
    jsonResult = Object.fromEntries(formData.entries())
    addProject(jsonResult);
    showAddProjectModal = false
}

the problem with this is that Object.fromEntries function does not handle multiple entries with the same key, it will just overwrite previous values.

So, I now have this function:

// Create an object from the form data, but converting repeated keys into an array
  const formDataToObject = (formData) => {
    let returnObj = {};
    for (const [key, value] of formData.entries()) {
      // If the key already exists on the object then it is a repeated key
      // If the value is already an array then just push the new value onto the array
      // Or convert the value to an array and push the new value onto the array
      if (returnObj[key]) {
        if (Array.isArray(returnObj[key])) {
          returnObj[key].push(value);
        } else {
          returnObj[key] = [returnObj[key], value];
        }
      } else {
        // If this is the first time we've seen this key then just add it to the object
        returnObj[key] = value;
      }
    }
    return returnObj;
  };

and now my handleSubmit loooks like this:

const handleSubmit = (event) => {
    event.preventDefault();
    const formData = new FormData(event.target);
    jsonResult = formDataToObject(formData)
    addProject(jsonResult);
    showAddProjectModal = false
}

Thanks for your help.

rikschennink commented 1 year ago

Glad to read that it's fixed and thanks for posting your solution :)

RossAddinall commented 1 year ago

:thumbsup: