vue-formulate icon indicating copy to clipboard operation
vue-formulate copied to clipboard

Inconsistent submit data for file input - inside and outside group input

Open suhasranganath opened this issue 4 years ago • 7 comments

Describe the bug Form submit data for a file input is [{"url": "https://example.com"}] when it's outside a group and the same will change to a complex object when it is inside a group.

Example complex output: { context: (...) fileList: (...) files: (...) input: (...) options: (...) results: (...) supportsDataTransfers: (...) uploadPromise: (...) }

Reproduction

CodePen:

https://codepen.io/megamind007/pen/YzVZWjx

Expected behavior Expected submit data for file input inside group is: [{name: "sample.png" url: "FILE_URL"}]

but getting { context: (...) fileList: (...) files: (...) input: (...) options: (...) results: (...) supportsDataTransfers: (...) uploadPromise: (...) }

suhasranganath avatar Jul 15 '21 06:07 suhasranganath

@justin-schroeder Any thoughts on this? is this expected?

suhasranganath avatar Aug 01 '21 05:08 suhasranganath

Hmm, not expected no. Are you seeing that data hit the server when posted?

justin-schroeder avatar Aug 02 '21 17:08 justin-schroeder

I am checking it inside the form submit handler (@submit on FormulateForm) and we are getting that complex object. This happens only if the file input is inside a group.

suhasranganath avatar Aug 04 '21 23:08 suhasranganath

I'm having the same issue. Note this bug also occures when the file upload is in a non-repeatable group.

@suhasranganath How did you fixed this, or did you find a workaround?

Because currently I can't send the form values via Axios because of the complex output. The complex output has endless recursion in it so it can't be converted to JSON and thus i'm not able to send the request at all.

Sanderruisseau avatar Sep 01 '21 11:09 Sanderruisseau

@Sanderruisseau Sorry for the delayed response. I am picking the required data inside the form submit handler. The complex output object has a property called results and that has the required data.

suhasranganath avatar Sep 07 '21 19:09 suhasranganath

I think I had the same issue with the recursion error when using file or image upload within a form (which works outside of a form). Probably the issue is caused by the opinionated approach to have files/image upload via form posting (binary data) which conflicts with the normal operation of the submit handler which uses json data. In my case I just wanted to get (small) images as b64 encoded to include with json post. I resolved this like so:

In the form I use file or image (difference in this case is just the preview) with delayed upload:

      <FormulateInput
        type="file"
        upload-behavior="delayed"
        label="Logo hochladen"
        help="Sample url help text"
        validation="mime:image/jpeg,image/jpg,image/png"
        name="logoimg"
        v-on:change="setLogo($event)"
        v-on:file-removed="removeLogo()"
      />

I set the uploaded file object (!) with setLogo(). Then, in the submit handler, I use a file reader to get the data and convert it to the b64 image data. Note: it is required to delete/overwrite the original object in the formValues (here: name=logoimg), because it is the one which generates the recursion error.

I think the documentation could be improved a bit ...

    setLogo (event) {
      const file = event.target.files[0]
      console.log("Setting logo to: ",file.name)
      this.logofile = file
    },

    async submitHandler (data) {
      this.formValues.isLoading = true
      try {

        console.log("Submit:",data)

        if (data.description && data.description[0] && data.description[0].logoimg) {
          // clear original logoimg in any case
          data.description[0].logoimg = ""
        }
        if (this.logofile) {
            const ld = new Promise((resolve) => {
              const reader = new FileReader()
              reader.onloadend = () => resolve(reader.result)
              reader.readAsDataURL(this.logofile)
            })
            const img = await ld  // load file/image data
            data.description[0].logoimg = img
            this.logo = img  // custom preview only
            data.description[0].logofile = this.logofile.name
            console.log("Submit new:",data)
        }
        await this.$axios.post('http://localhost:9000/php/rest.php', data)
        console.log("Submitted:",data)
        this.formValues.submitted = true
      } catch (err) {
        console.log("Error !!! ",err)
        this.formValues.submitted = false
      }
    },

Maybe this could be done more elegant by intercepting submit-raw to load the file and place the result into the formValues.

digital-codes avatar Dec 13 '21 18:12 digital-codes

I have the same problem since I am using repeatable groups, I still can't find any solution Captura de Pantalla 2023-07-07 a la(s) 12 49 04

seballero avatar Jul 07 '23 16:07 seballero