I'm using a multi-step form in Vue.js to send multiple files to a Laravel backend. The form gives the user the ability to add multiple users to the database. Each user requires a file to be uploaded along with it.
Files are initially stored in state using Vuex. Each file is pushed to a files array in store.js
When the user submits the form, the files array looks as follows:
When the user submits the form I'm adding all the individual form data including the files array to a new FormData() object like so:
let fd = new FormData();
// append each file
for( var i = 0; i < store.state.files.length; i++ ){
let file = store.state.files[i];
fd.append('files[' + i + ']', file);
console.log(file);
}
// append rest of form data
fd.append('appointments', store.state.appointments);
fd.append('business_details', store.state.business_details);
fd.append('business_names', store.state.business_names);
fd.append('directors', store.state.directors);
fd.append('share_amount', store.state.share_amount);
fd.append('shareholders', store.state.shareholders);
Once all the form data is added I use Axios to send the form data to my Laravel backend.
axios.post('/businesses', fd, {
headers: {
'content-type': 'multipart/form-data'
}
})
.then(response => {
console.log(response);
this.completeButton = 'Completed';
})
.catch(error => {
console.log(error)
this.completeButton = 'Failed';
})
Inside my Laravel BusinessController I then want to Log::debug($_FILES)
to see what files were sent along but all I get is an empty array.
[2018-10-05 16:18:55] local.DEBUG: array (
)
I've checked that the headers I'm sending includes 'multipart/form-data'
and that I'm appending all my form data to new FormData() but I cannot figure out why the server receives an empty $_FILES array.
UPDATE 1: If I Log::debug($request->all());
I get:
If I try to store the objects in that file like so:
foreach ($request->input('files') as $file) {
$filename = $file->store('files');
}
I get the following error:
[2018-10-06 09:20:40] local.ERROR: Call to a member function store() on string
Try this case:
var objectToFormData = function (obj, form, namespace) {
var fd = form || new FormData();
var formKey;
for (var property in obj) {
if (obj.hasOwnProperty(property)) {
if (namespace) {
formKey = namespace + '[' + property + ']';
} else {
formKey = property;
}
// if the property is an object, but not a File,
// use recursivity.
if (typeof obj[property] === 'object' && !(obj[property] instanceof File)) {
objectToFormData(obj[property], fd, property);
} else {
// if it's a string or a File object
fd.append(formKey, obj[property]);
}
}
}
return fd;
};
Reference : objectToFormData
Axios :
axios.post('/businesses', fd, {
transformRequest: [
function (data, headers) {
return objectToFormData(data);
}
]
})
.then(response => {
console.log(response);
this.completeButton = 'Completed';
})
.catch(error => {
console.log(error)
this.completeButton = 'Failed';
})