11

I am trying to upload multiple images using vuejs and axios but on server side i am getting empty object. I added multipart/form-data in header but still empty object.

submitFiles() {
    /*
      Initialize the form data
    */
    let formData = new FormData();

    /*
      Iteate over any file sent over appending the files
      to the form data.
    */
    for( var i = 0; i < this.files.length; i++ ){
      let file = this.files[i];
      console.log(file);
      formData.append('files[' + i + ']', file);
    }

    /*`enter code here`
      Make the request to the POST /file-drag-drop URL
    */
    axios.post( '/fileupload',
      formData,
      {
        headers: {
            'Content-Type': 'multipart/form-data'
        },
      }
    ).then(function(){
    })
    .catch(function(){
    });
  },

HTML:

<form method="post" action="#" id="" enctype="multipart/form-data">
    <div class="form-group files text-center" ref="fileform">
        <input type="file"  multiple="multiple">
        <span id='val'></span>
        <a class="btn"  @click="submitFiles()" id='button'>Upload Photo</a>
        <h6>DRAG & DROP FILE HERE</h6>
    </div>

My Server side code:

class FileSettingsController extends Controller
{
    public function upload(Request $request){
        return $request->all();
    }
}

Output:

{files: [{}]}
files: [{}]
0: {}

Console.log() result: File(2838972) {name: "540340.jpg", lastModified: 1525262356769, lastModifiedDate: Wed May 02 2018 17:29:16 GMT+0530 (India Standard Time), webkitRelativePath: "", size: 2838972, …}

Daniel
  • 2,621
  • 2
  • 18
  • 34
weaver
  • 453
  • 1
  • 8
  • 21

3 Answers3

31

You forgot to use $refs. Add ref to your input:

<input type="file" ref="file" multiple="multiple">

Next, access your files like this:

submitFiles() {

    const formData = new FormData();

    for (var i = 0; i < this.$refs.file.files.length; i++ ){
        let file = this.$refs.file.files[i];
        formData.append('files[' + i + ']', file);
    }

    axios.post('/fileupload', formData, {
        headers: {
            'Content-Type': 'multipart/form-data'
        },
      }
    ).then(function(){
    })
    .catch(function(){
    });
},

This should be works.

Daniel
  • 2,621
  • 2
  • 18
  • 34
  • What about `dd($request->file('files'))` in your controller? What output have you got? – Daniel Feb 04 '19 at 16:27
  • `array:1 [ 0 => UploadedFile {#756 -test: false -originalName: "540340.jpg" -mimeType: "image/jpeg" -error: 0 #hashName: null path: "C:\xampp\tmp" filename: "php44C8.tmp" basename: "php44C8.tmp" pathname: "C:\xampp\tmp\php44C8.tmp" extension: "tmp" realPath: "C:\xampp\tmp\php44C8.tmp" aTime: 2019-02-04 16:32:27 mTime: 2019-02-04 16:32:27 type: "file" writable: true readable: true executable: false file: true dir: false link: false linkTarget: "C:\xampp\tmp\php44C8.tmp" } ]` – weaver Feb 04 '19 at 16:37
  • 1
    So you got it, now you need to store them. – Daniel Feb 04 '19 at 16:39
  • if there are fields that contain strings how do we combine them? – Cak Bud Dec 03 '22 at 18:36
  • @AhmadBudairi, you have to append data with the string value, ie. `formData.append('title', this.form.title);` – Daniel Dec 03 '22 at 23:05
4

If anyone wondering, "How can I send also data with it", there you go:

formData.append('name[' + this.name + ']', name);
formData.getAll('files', 'name');
1

For Composition API this should work:

const files = ref([])

function save() {
  let formData = new FormData()
  for (let file of files.value) {
    formData.append('files', file)
  }
  axios.post('/upload', formData, {
    headers: {
      'Content-Type': 'multipart/form-data',
    },
  })
  .then((response) => {
  })
}
goodgrief
  • 378
  • 1
  • 8
  • 23
  • For Laravel, at least, it seems I can't just send multiple "files" and I have to manually add an array notation, i.e. `files[0] ... files[3]` while using append. – Brendan Jan 10 '23 at 01:30