5

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)
TJ Weems
  • 1,086
  • 3
  • 21
  • 37
  • A `File` encapsulates the data. https://developer.mozilla.org/en-US/docs/Web/API/File – Roy J Nov 26 '18 at 14:27
  • what exactly are you trying to achieve and what is the error you are having ? – Ewomazino Ukah Nov 26 '18 at 14:35
  • @MazinoSUkah, I am trying to submit my form data object with the `this.$store.dispatch('uploadTodos', formData);`, however my `vuex` method `uploadTodos` contains no data. Please view updated question for `vuex` method – TJ Weems Nov 26 '18 at 14:38
  • @RoyJ, when I `console.log(pair)` it shows the contents of the `formData` object however once it reaches my `vuex` method it seems to be empty.... – TJ Weems Nov 26 '18 at 14:40

2 Answers2

5

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>
Ewomazino Ukah
  • 2,286
  • 4
  • 24
  • 40
  • yes I am now getting the same results. I guess I am having an issue with the data being received on the back end. I appreciate the help! – TJ Weems Nov 26 '18 at 15:04
  • you are welcome..what language/framework are you using on the backend ? – Ewomazino Ukah Nov 26 '18 at 15:05
  • Laravel 5.6. I added the `maatwebsite` package, so I can upload excel files, however when I reach my controller method I am doing something wrong. any experience with it? – TJ Weems Nov 26 '18 at 15:07
  • I have experience with laravel... Can you update your question showing what you have tried for the laravel backend? – Ewomazino Ukah Nov 26 '18 at 15:10
  • so the original issue I was having with backend is solved however apparently the version of `maatwebsite` I am using does not support imports? Please see the updated question...and here is the article saying that imports are not supported [click here](https://stackoverflow.com/questions/49473098/call-to-undefined-method-maatwebsite-excel-excelload) – TJ Weems Nov 26 '18 at 15:32
  • as discussed here https://github.com/Maatwebsite/Laravel-Excel/issues/1643 i don't think its possible to achieve 'imports' with version 3.0 :( Why not use a version that supports it ? – Ewomazino Ukah Nov 26 '18 at 15:38
  • I guess my concern would be the ending support for the older version. Would it be maintained for new versions of laravel coming out? Is this a reasonable concern? – TJ Weems Nov 26 '18 at 15:54
  • IMHO i don't think that should be a concern – Ewomazino Ukah Nov 26 '18 at 15:59
  • 1
    please see my answer post for the `maatwebsit/excel` issue. It turns out it does support imports. – TJ Weems Nov 26 '18 at 18:13
1

This post answers the second part of the question. At first from what I read maatwebsite/excel version 3.0 does not support import. However I am using version 3.1.0 which does support imports. However the method for importing still does not suppport Excel::load(). You should instead use Excel::import() and follow the given rules for passing in parameters. Which of course can be modified to suit your needs. But anyways here is a simple example of how I am using it for anyone interested.

First create import file for whatever model it is. For me it is Todos.

<?php

namespace App\Imports;

use App\Todo;

use Maatwebsite\Excel\Concerns\ToModel;

class TodoImport implements ToModel
{
    /**
    * @param array $row
    *
    * @return \Illuminate\Database\Eloquent\Model|null
    */
    public function model(array $row)
    {
        return new Todo([
            'user_id'  => $row[0],
            'todo'     => $row[1],
        ]);
    }
}

next you have your controller handling the file, and passing it to the todosimport file

 public function importExcel(Request $request) 
    {

        if (empty($request->file('file')->getRealPath())) {
            return back()->with('success','No file selected');
        }
        else {
        Excel::import(new TodoImport, $request->file('file'));

        return response('Import Succesful, Please Refresh Page');
        }

    }

notice the Excel::import(). I pass in the new Todo model and the file received.

of course for me since I am doing it by ajax I use this route to ping the method

Route::post('/import', 'TodosController@importExcel');
TJ Weems
  • 1,086
  • 3
  • 21
  • 37