Search code examples
vue.jsfile-uploadaxiosform-data

How To Use FormData() For Uploading File In Vue


So I had asked a question previously, and got a little bit of help as far as logging the results however my results are not making sense.

So I have a input

<input type="file" name="import_file" v-on:change="selectedFile($event)">

The v-on:change binds the selected file to my data object this.file

selectedFile(event) {
      this.file = event.target.files[0]
    },

and then I submit the file with this method

uploadTodos() {
  let formData = new FormData();
  formData.append('file', this.file);
  for(var pair of formData.entries()) {
    console.log(pair[0]+ ', '+ pair[1]); 
   }
   this.$store.dispatch('uploadTodos', formData);
 }

However when I submit it seems there is no data attached to formData because my logged result is this

file, [object File]

shouldn't I have my actual data appended to the formData object??

I have referenced other articles on how to post but I am not getting the desired results.

article 1 article2

uploadTodos(context, file) {
      console.log(file)
      axios.post('/import', file,{ headers: {
        'Content-Type': 'multipart/form-data'
      }})
      .then(response => {
        console.log(response.data)
        context.commit('importTodos', response.data)
      })
      .catch(error => {
        console.log(error.response.data)
      })
    }

when I console.log(file) the formData object is empty

Backend Question So my issue with Laravel on the backend is with the maatwebsite package. From what I have seen is the 3.0 version does not yet support imports. And the only work around suggested is to install version 2.0? Is this still the only workaround? Here is the controller method

public function importExcel(Request $request) 
    {

        if (empty($request->file('file')->getRealPath())) {
            return back()->with('success','No file selected');
        }
        else {
        $path = $request->file('file')->getRealPath();
        $inserts = [];
        Excel::load($path,function($reader) use (&$inserts)
        {
            foreach ($reader->toArray() as $rows){
                foreach($rows as $row){
                    $inserts[] = ['user_id' => $row['user_id'], 'todo' => $row['todo']];
                };
            }
        });

        if (!empty($inserts)) {
            DB::table('todos')->insert($inserts);
            return back()->with('success','Inserted Record successfully');                  
        }


        return back();
        }

    }

The line not suppported by version 3.0 is this

Excel::load($path,function($reader) use (&$inserts)

Solution

  • I have reproduced your code and it seems to be working fine

    when I console.log(file) the formData object is empty

    Yeah the output should be an empty object when you console, that's the way javascript works.

    after casting the output to an array i get the output in the image below:

    enter image description here

    const store = new Vuex.Store({
      actions: {
        uploadTodos(context, file) {
          console.log([...file])
          axios.post('/import', file,{ headers: {
            'Content-Type': 'multipart/form-data'
          }})
          .then(response => {
            console.log(response.data)
            context.commit('importTodos', response.data)
          })
          .catch(error => {
            console.log(error.response.data)
          })
        }
      }
    })
    
    const app = new Vue({
    	store,
      data: {
      	file: null
      },
      methods: {
      	selectedFile(event) {
      	    console.log(event);
      	      this.file = event.target.files[0]
      	    },
        uploadTodos() {
      		let formData = new FormData();
      		formData.append('file', this.file);
      		for(var pair of formData.entries()) {
        		console.log(pair[0]+ ', '+ pair[1]); 
       		}
       		this.$store.dispatch('uploadTodos', formData);
     		}
      },
      el: '#app'
    })
    <script src="https://unpkg.com/vue"></script>
    <script src="https://unpkg.com/vuex"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <div id="app">
      <input type="file" name="import_file" @change="selectedFile($event)">
      <button @click="uploadTodos">
       Submit 
      </button>
    </div>