Reputation: 1064
The challenge is with sending a patch request with an attachment to Laravel
backend from a Vue
axios
request. I tried using objectToFormData to send a post request and it worked just fine. However, the same objectToFormData
does not even send any fields from the form with a patch request.
Template
<template>
<div>
<div id="medicalForm" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="acertLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header bg-success">
<h4 class="modal-title text-white" id="acertLabel">{{ editMode ? 'Edit Medical Record' : 'New Medical Record'}} </h4>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
</div>
<form @submit.prevent="editMode ? updateRecord(): newFile()" id="inModal" enctype="multipart/form-data" @keydown="medicalForm.onKeydown($event)">
<div class="modal-body">
<div class="form-group">
<label>Desciption <span class="text-danger">*</span></label>
<input type="text" v-model="medicalForm.description" autocomplete="off" name="description" placeholder="describe document here" class="form-control" :class="{ 'is-invalid': medicalForm.errors.has('description') }" >
<has-error :form="medicalForm" field="description"></has-error>
</div>
<div class="form-group">
<label v-if="!editMode">Choose File <span class="text-danger"> *</span></label>
<label v-if="editMode"> Replace Existing File <span class="text-danger"> </span></label>
<input type="file" @change="handleFile" class="form-control-file" :class="{ 'is-invalid': medicalForm.errors.has('file') }">
<has-error :form="medicalForm" field="file"></has-error>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-light waves-effect" data-dismiss="modal">Close</button>
<button v-show = "!editMode" type="submit" class="btn btn-success waves-effect waves-light">Create</button>
<button v-show = "editMode" type="submit" class="btn btn-warning waves-effect waves-light">Update</button>
</div>
</form>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div>
</div>
</template>
Script
<script>
export default {
name: 'Medical',
data(){
return {
id: this.$route.params.id,
medicals:{},
editMode: false,
medicalForm: new Form({
'record_id': '',
'user_id': this.$route.params.id,
'description': '',
'file': null,
}),
}
},
methods:{
handleFile(e){
let selectedFile = e.target.files[0];
this.medicalForm.file = selectedFile;
},
updateRecord(){
this.medicalForm.patch('/api/medicals/'+this.medicalForm.record_id, {
transformRequest: [function (data, headers) {
return objectToFormData(data)
}],
onUploadProgress: e => {
//file is uploading
}
})
.then(response => {
//updated
})
.catch(errors => {
//not updated
});
},
newFile(){
this.medicalForm.post('/api/medicals', {
transformRequest: [function (data, headers) {
return objectToFormData(data)
}],
onUploadProgress: e => {
console.log('Saving your data...')
}
})
.then(response => {
//ok
})
.catch(errors => {
//not ok
});
},
}
}
</script>
Controller
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Medical;
class MedicalController extends Controller
{
public function store(Request $request)
{
dd($request); works fine
}
public function update(Request $request, $id)
{
dd($request); // does not return any values
}
}
Upvotes: 0
Views: 94
Reputation: 2387
Manually setting the method of request may help solving the problem.
I have tried many times to send binary data via axios
and I discovered that the best method is by wrapping your data in a FormData
object. Please have the following code as reference:
<template>
<input @change="uploadFile" type="file">
</template>
<script>
// ...
uploadFile: function(event)
{
var data = new FormData();
data.append('file', event.target.files[0]); // can be a list of files
// data.append('_method', 'PATCH'); should not be necessary
// post
axios.patch('/url-here', data)
// response
.then(response=>{
this.toast('File uploaded! '+ response.data.name)
})
},
// ..
</script>
Then in your Controller
parse the data as you normally would:
public function store(Request $request)
{
$validated = $request->validate([
'file' => 'required|file|max:4096|...',
]);
dd ($validated);
}
Upvotes: 1