Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

File Upload using vuetify 2 v-file-input and axios

First of all, i've checked questions file-upload-in-vuetify and vuetify-file-uploads. But the solutions there didn't work.

I'm trying to use vuetify 2 <v-file-input> to send multiple PDF files. I created the FormData object and appended all my files but when i attempt to submit it doesn't reach my backend. I just get an empty object. this is my code:

Template:

<v-layout>
    <v-flex>
      <v-file-input show-size counter chips multiple label="Arquivo Geral" ref="myfile" v-model="files"></v-file-input>
    </v-flex>
    <v-flex>
      <v-btn color="primary" text @click="submitFiles">test</v-btn>
    </v-flex>
</v-layout>

script:

data() {
    return {
        files: null,
    }
}
methods: {
    submitFiles(){
        let formData = new FormData()

        if(this.files){

            for( let file in this.files){
                formData.append("cave", file)
            }

            console.log(formData.getAll("cave"))
            console.log(this.files)
            axios.post('https://eniwp6w65oc77.x.pipedream.net/', 
                        {
                            files: formData,
                            test: "test"
                        }, 
                        { 
                            headers: { 
                                'Content-Type': 'multipart/form-data'
                            } 
                        }).then( response => {
                            console.log('Success!')
                            console.log({response})
                        }).catch(error => {
                            console.log({error})
                        })
        }
        else {
            console.log('there are no files.')
        }
    }
}

my response body and header in requestbin:

body:

{
    "files": {},
    "test": "test"
}

header:

host: eniwp6w65oc77.x.pipedream.net
Accept: application/json, text/plain, */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,pt;q=0.8,gl;q=0.7
Cache-Control: no-cache
Content-Type: multipart/form-data
Origin: http://localhost:8000
Pragma: no-cache
Referer: http://localhost:8000/
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36
Content-Length: 28
Connection: keep-alive
like image 376
Marcelo Fonseca Avatar asked Sep 03 '19 14:09

Marcelo Fonseca


People also ask

How do I upload files to Axios?

– First we import Axios and Bootstrap, then we write some HTML code for the UI. For 2 onClick events, there are 2 functions that use Axios for working with Rest API Server: uploadFile() : POST form data with a callback for tracking upload progress. getFiles() : GET list of Files' information.


1 Answers

First of all, you have two bugs in code:

  1. Where you're preparing FormData object. You can't use for-in loop for iterating an array of files here since for-in loops over enumerable property names of an object. You can use for-of loop instead.

  2. You're using formData in brackets. You should pass FormData instance, not JSON. To send aditional paramaters like "test" using FormData do formData.append("test", "foo bar")

Also check that your backend properly handles multipart/form-data data. If your backend is in Node.js and Express.js then you should use proper body parser middleware, for example multer

Here is a working example:

Node.js/Express.js backend:

const multer = require("multer"),
...    
router.post("/upload-files", multer().array("files"), function (req, res) {
    console.log("body: ", req.body);
    console.log("files:", req.files);
    return res.sendStatus(200);
});

frontend:

submitFiles() {
    if (this.files) {
        let formData = new FormData();

        // files
        for (let file of this.files) {
            formData.append("files", file, file.name);
        }

        // additional data
        formData.append("test", "foo bar");

        axios
            .post("/upload-files", formData)
            .then(response => {
                console.log("Success!");
                console.log({ response });
            })
            .catch(error => {
                console.log({ error });
            });
    } else {
        console.log("there are no files.");
    }
}

Note that you don't need to set Content-Type header manually when you pass FormData as a POST request body

like image 67
Yurii Semeniuk Avatar answered Sep 17 '22 12:09

Yurii Semeniuk