Components. Send request with file via vue.http.post() - laravel

I have vuejs2 component on page (single file component). It's a simple bootstrap modal window with one file input. I only need to upload one file (no mutlifile upload or etc.)
What is in file:
<template>
<div class="modal fade" id="upload-file-modal" tabindex="-1" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title">Upload file</h4>
</div>
<form id="app-file-upload-form" name="appFileUploadForm" #submit.prevent="uploadAppFile" novalidate enctype="multipart/form-data">
<div class="modal-body">
<div class="form-group">
<label for="app-file-fileinput">File</label>
<input type="file" name="file" id="app-file-fileinput" class="form-control" v-el="file" #change="attachFile">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-primary">Upload</button>
</div>
</form>
</div>
</div>
</div>
<script>
export default {
data() {
return {
file: ''
}
},
methods: {
attachFile(e) {
var files = e.target.files || e.dataTransfer.files;
if (!files.length)
return;
this.file = files[0];
},
uploadAppFile() {
console.log(this.file);
Vue.http.post('/api/v1/apps/' + this.appId + '/files', { file: this.file}).then((response) => {
console.log(response);
}, (response) => {
console.log(response);
});
}
}
}
So i have laravel controller for handle it.
public function upload(Request $request)
{
$attachedFile = $request->file;
return response()->json($request->all());
}
I put return response->json() for kinda debug this. When i attach file, file attaching to component(model?) field and not empty. But when vue.http.post happening the file comes to empty object.
First is console.log(file)
Second is server response.
I also tried with FormData()... it didn't work.
ps: i cut version field from code.

After few more times with formdata i got file upload working. Just put variable inside method.
uploadAppFile() {
let data = new FormData();
data.append('file', this.file);
Vue.http.post('/api/v1/apps/' + this.appId + '/files', data).then((response) => {});
}

Related

Bootstrap modal is disappearing after AJAX response

I use AJAX to send data inside a bootstrap modal to a controller in ASP.NET MVC. After its operation is completed inside this controller, a success or failure response is sent back to bootstrap modal using following code:
Controller:
[HttpPost]
public JsonResult Action([Bind(Include = "Id,firstName,lastName")] InqueryViewModel model)
{
JsonResult json = new JsonResult();
if (ModelState.IsValid)
{
Inquery inquery = new Inquery();
inquery.firstName = model.firstName;
inquery.lastName = model.lastName;
var result = SaveInqueries(inquery);
json.Data = new { Success = true };
}
else
{
json.Data = new { Success = false, Message = "Unable to perform an action on sending" };
}
return json;
}
As you notice above, code is dividing the logic into 2 types of responses, i.e., success or failure. Following code inside bootstrap model is used to handle this response:
JavaScript
<script>
$("#actionButton").click(function () {
$.ajax({
url: '#Url.Action("Action","Home")',
type: "post",
data: $("#actionForm").serialize()
})
.done(function (response) {
if (response.Success) {
//data is saved.
$(".alert-success").show();
$("#actionForm").hide();
}
else {
$(".errorDiv").html(response.Message);
}
});
});
</script>
Above code is working as expected if response is a success, but its not showing .errorDiv on a failure response. Instead, bootstrap modal is being disappeared. Following is bootstrap modal code:
HTML:
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Get Your Survey</h5>
<button type="button" class="close" data-bs-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div class="alert alert-success collapse">
<span>
Success
</span>
</div>
<form id="actionForm">
<div class="form-group">
#Html.TextBoxFor(m => m.firstName, new { placeholder = "First Name", #class = "form-control form-control-sm" })
</div>
<div class="form-group">
#Html.TextBoxFor(m => m.lastName, new { placeholder = "Last Name", #class = "form-control form-control-sm" })
</div>
<button id="actionButton" class="data-btn btn btn-outline-success" type="submit">
<i class='fa fa-paper-plane'></i>
Send
</button>
</form>
<div class="errorDiv">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
</div>
</div>
Can anyone see why this program is behaving like this?
Thank you.

how do I send an image from vuejs to laravel server for upload

this is my form
<div class="modal" id="profileModal" tabindex="-1" role="dialog" aria-labelledby="profileModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header text-center">
<h5 class="modal-title">Upload Profile Picture</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div class="form-group">
<div class="row">
<div class="col-6">
<label>Profile Picture</label>
<input ref="image" id="image" type="file" name="image" accept="image/*" class="form-control" style="border: none" #change="loadImage($event)">
</div>
<div class="col-6">
<img :src="this.image_file" class="uploading-image img-thumbnail" height="128" alt="Preview" />
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-success" #click="submitImage">Upload <i class="fas fa-user-plus"></i></button>
</div>
</div>
</div>
</div>
this method is triggered when I select an image so I can preview before upload, it also stores the image in a variable I have created
loadImage(e){
this.file = e.target.files[0];
const reader = new FileReader();
reader.readAsDataURL(this.file);
reader.onload = e =>{
this.image_file = e.target.result;
};
console.log(this.file);
},
the above code works perfectly and am able to preview the image
these are my variables
formData: new FormData(),
file: null,
image_file: '',
this code handles the sending of request to the server using axios
submitImage(){
this.formData.append('image', this.file, this.file.name);
console.log(this.formData);
axios.put( '/data/profile/image',
this.formData,
{
headers: {
'Content-Type': 'multipart/form-data'
}
},
).then(function(response){
Fire.$emit('profileUpdate');
console.log(response.data);
swal.fire(
'Update',
'Profile Picture Updated Successfully',
'success'
);
})
.catch(function(error){
console.log(error.data);
});
$('#profileModal').modal('hide');
},
this is my laravel server side, an just checking if the request has a file
public function uploadImage(Request $request){
if($request->hasfile('image')){
return "Yes";
}
else{return "No";}
}
the above code returns 'NO' meaning there is no file attached to the formData
please is there anything I am not doing right?
Laravel has an issue receiving form-data from ajax requests using the HTTP VERB PUT, try the same thing using POST instead.
Links: https://github.com/laravel/framework/issues/13457

Uploading pdf file in laravel vuejs Axios

I have created a project for bookshop and in the section of employee information I want to upload a PDF file using code given below.it give me the below error.I have been trying since few days but I could not get the solution if there is any sample way please guide me
any help will be highly appreciated
The given data was invalid.","errors":{"file":["The file field is
required.
controller code is
public function store(Request $request)
{
$DocumentType= new DocumentType();
$this->validate($request,[
'name'=>'required',
'file' => 'required',
]);
$DocumentType->name = $request->input('name');
$fileName = time().'.'.$request->file->extension();
$request->file->move(public_path('Files'), $fileName);
$DocumentType->file = $name;
$DocumentType->save();
return response()->json($DocumentType);
}
Vue code is
<template>
<div class="container">
<div
class="modal fade"
id="addNew"
tabindex="-1"
role="dialog"
aria-labelledby="addNewLabel"
aria-hidden="true"
>
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" v-show="!editMode" id="addNewLabel">ثبت اسناد جدید</h5>
<h5 class="modal-title" v-show="editMode" id="addNewLabel">تمدید اسناد</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true" style="margin-right: 317px;">×</span>
</button>
</div>
<form
#submit.prevent="editMode ? updateDocumentType() : createDocumentType()"
enctype="multipart/form-data"
>
<div class="modal-body">
<div class="form-group">
<input
v-model="form.name"
placeholder="نام"
type="text"
name="name"
class="form-control"
:class="{ 'is-invalid': form.errors.has('name') }"
/>
<has-error :form="form" field="name"></has-error>
</div>
<div class="form-group">
<label for="file" class="col-sm-4 control-label">File</label>
<div class="col-sm-12">
<input
type="file"
class="form-input"
:class="{ 'is-invalid': form.errors.has('file') }"
id="file"
name="file"
/>
<has-error :form="form" field="file"></has-error>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger" data-dismiss="modal">لغو</button>
<button
v-show="editMode"
:disabled="form.busy"
type="submit"
class="btn btn-success"
>تمدید</button>
<button
v-show="!editMode"
:disabled="form.busy"
type="submit"
class="btn btn-primary"
>ثبت</button>
</div>
</div>
</form>
</div>
</div>
</div>
</template>
</div>
<script>
createDocumentType() {
// axios.get("api/getAllDocumentTypeDocumentType").then(response => {
// let data = response.data;
if (this.form.name == "") {
toast.fire({
type: "warning",
icon: "warning",
html: "<h5>نام لازم است.</h5>"
});
}
// else if (this.form.file == "") {
// toast.fire({
// type: "warning",
// icon: "warning",
// html: "<h5>لطفا،اسناد را انتخاب نماید.</h5>"
// });
// }
else {
this.form
.post("api/DocumentType")
.then(() => {
// the below function will be use to reload the page
// this.$emit("refreshPage");
$("#addNew").modal("hide");
toast.fire({
icon: "success",
type: "success",
html: "<h5> اسنادموافقانه اجاد گردید</h5>"
});
Fire.$emit("refreshPage");
this.form.reset();
// this.$Progress.finish();
})
.catch(er => {
console.log(er);
});
}
}
</script>
Migration table code
public function up()
{
Schema::create('document_types', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name');
$table->string('file')->nullable();
$table->softDeletes();
$table->timestamps();
});
}
Code in API route
Route::apiResources(['DocumentType'=>'API\DocumentTypeController']);
Route::get('getAllDocumentType','API\DocumentTypeController#getAll');
The given data was invalid.","errors":{"file":["The file field is required. This error is because there is no existing file in your payload upon submission of your form.
in your form, bind data to your input file like what you did to your input name. like this
<input
type="file"
v-model="form.file"
class="form-input"
:class="{ 'is-invalid': form.errors.has('file') }"
id="file"
name="file"
/>
Or, attach an event to this file input and process the file provided. like this
<input
type="file"
class="form-input"
:class="{ 'is-invalid': form.errors.has('file') }"
id="file"
name="file"
#change="selectFile"
/>
Then in your methods, create also a selectFile function
methods: {
selectFile(file) {
if(file == "") return false
this.form.file = file.target.files
console.log(this.form.file)
}
}

Laravel Vue js Response Result not updating after axios call

I have vue component.After axios response counter not updating on popup. showInterest function is called on created method.
<template>
<span class="interested-button">
<a data-toggle="modal" data-target="#buyModel" #click="showInterest(idea_id, owner_id)">
<i class="fa fa-usd" aria-hidden="true"></i> Interested to buy?
</a>
<div
class="modal fade"
id="buyModel"
tabindex="-1"
role="dialog"
aria-labelledby="buyModelLabel"
aria-hidden="true"
>
<div class="modal-dialog" role="ideabuy">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="buyModelLabel">How much you are willing to spend?</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
{{ sharedPriceCount }}
<template v-if="sharedPriceCount == 0">
<form #submit.prevent="saveIdeaPrice">
<div class="modal-body">
<div class="form-group">
<input type="text" v-model="price" class="form-control">
</div>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-success">Save</button>
</div>
</form>
</template>
<template v-else>
<div class="modal-body">
<div class="form-group">You have already shown interest for this Idea.</div>
</div>
</template>
</div>
</div>
</div>
</span>
</template>
<script>
import mixins from "../mixins";
export default {
name: "buyProduct",
mixins: [mixins],
props: ["input_name", "idea_id", "owner_id"],
data() {
return {
result: [],
loading: false,
price: 0,
sharedPriceCount: 0
};
},
created() {},
mounted() {},
methods: {
saveIdeaPrice() {
axios
.post("/idea-buy-price", {
id: this.idea_id,
owner: this.owner_id,
price: this.price
})
.then(res => {
this.loading = false;
})
.catch(res => (this.loading = false));
},
showInterest(idea_id, owner_id) {
let _self = this;
axios
.get("/idea-buy-price/" + idea_id + "/" + owner_id)
.then(
function(response) {
_self.result = JSON.stringify(response.data.data);
_self.sharedPriceCount = response.data.data.length;
console.log(_self.sharedPriceCount);
_self.loading = false;
}.bind(_self)
)
.catch(
function(error) {
_self.loading = false;
}.bind(_self)
);
},
updateCall() {}
}
};
</script>
I am getting Array data through api call.but on popup its not working properly.I want to update this.sharedPriceCount when popup open.to show the popup content.without refreshing page.
Anyone can help me on this?
If result and loading are updated then please disregard following:
I had trouble with this. within function in axios call.
Solved it by defining
var _self = this;
before axios call and using _self within response function

Laravel 5, Vue 2 - send html form via controller and bind submit action to the component method

I am trying to bind action to component method, to the button which is sent via ajax response (json).
So far I have two Vue components - Service and Modal.
Service:
<template>
<div>
<h1>Services ({{ services.length }})</h1>
<div class="services-actions">
<button type="button" class="btn btn-primary" #click="openModal">Add Service</button>
</div>
<div class="services" v-for="(service, index) in services" :key="service.id">
<p>{{ service.name }}</p>
</div>
</div>
</template>
<script>
export default {
data(){
return {
services: []
}
},
methods: {
getAll(){
axios.get('/admin/services/all', {})
.then((response) => {
this.services = response.data
})
},
openModal(){
axios.get('/admin/services/create', {})
.then((response) => {
Event.$emit('modal:show', response.data)
})
},
save(){
console.log('test');
}
},
mounted(){
this.getAll()
}
}
</script>
Modal:
<template>
<div class="modal fade" tabindex="-1" role="dialog" id="main-modal">
<div class="modal-dialog" role="document">
<div class="modal-content">
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
</template>
<script>
export default {
mounted(){
let mainModal = $('#main-modal')
Event.$on('modal:show', (html) => {
mainModal.find('.modal-content').html(html)
mainModal.modal('show')
})
Event.$on('modal:hide', () => {
mainModal.modal('hide')
})
}
}
</script>
View file:
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title">Modal title</h4>
</div>
<form id=service-store action='/admin/service/store'>
<label for="name">Name</label>
<input type="text" name=name id=name>
</form>
<div class="modal-body">
<p>One fine body…</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save changes</button>
</div>
Is it possible bind save changes to the Service component save method when I click the Save changes button?

Resources