Is FormData object required with Vuejs to upload file to laravel backend? - laravel

Is the FormData object absolutely necessary to work with files and to upload them to my backend made with laravel?
Secondly, would it be a good practice to wrap all form inputs in a FormData object, even non file input?
Currently I try this
<input type="file" #change="onVideoSelected" name="explenationVideo">
My method logic:
onVideoSelected(event) {
this.form.video = event.target.files[0];
}
My data structure
data() {
return {
form: {
name : '',
contentType : 'video',
imageGroup : [],
video : null,
difficulty : '',
}
}
}
And when I submit
axios.post('/backoffice/exercises', this.form)
.then(({data}) => {
this.messages.push('Exercice ajouté!');
});
But when I try to view the detail in the backend like
dd($request->file('video'));
I have a null value.

Related

Not getting any data from api controller into vue component

I have a component in vue 3 named index which gets the user form data and passes it onto api controller in laravel.
async submitForm() {
try {
await axios.post(
"/api/show",
{
firstname: this.form.firstname,
email: this.form.email,
},
);
} catch (error) {
console.error("error");
}
},
and I'm trying to fetch the data sent into the controller via following method onto another component named show and all I'm getting is empty string and I don't understand the reason. Any guide would be really appreciated.
loadProductDetails() {
axios.post("api/show")
.then(({data}) => (this.products = data));
},
Solved the issue. It was because I was trying to get response from two different routes but the first one was already fetching the post response data and second one was returning the empty string and replacing the data I already recieved from the response.
try {
axios
.post("/api/show", {
firstname: this.form.firstname,
email: this.form.email,
selectedAnswer: this.form.selectedAnswer,
selectedCategory: this.form.selectedCategory,
})
.then((res) => {
localStorage.setItem("show", JSON.stringify(res.data));
});
} catch (error) {
console.error("error");
}
Simply saving the response data into local storage and getting it from another component solved the issue.
loadProductDetails() {
this.products = JSON.parse(localStorage.getItem('show'));
}

Front End File Upload using Vue and Winter Cms

I'm trying to upload images from a Vue frontend via Illuminate/Http/Request to WinterCMS.
Vue finds the file and i can console.log the File object, but I'm unsure how to get this over the api. for example I've tried
public function saveImage(Request $req){
$images = $req->files('images');
}
which doesn't work, nor does
public function saveImage(Request $req){
$images = $req['images'];
}
I'm using a controller to handle my routes eg:
Route::post('/saveImage', 'Author\Project\Controllers\ProductControl#saveImage');
I've added an attachOne relation to the plugin as usual and my form has enctype="multipart/form-data"
I've had this problem before and got around it by converting images to base64 but this project will have quite a few images and I don't want to go down that route again.
Any suggestions greatly appreciated
You can send images as regular post and use regular $request->file('images') method in your Laravel controller.
You can use Javascript FormData object. For example;
<div>
<input type="file" #change="handleImages" multiple>
<button #click="uploadImages">Upload!</button>
</div>
data: () => ({
images: []
}),
methods: {
handleImages (event) {
this.images = event.target.files
},
uploadImages () {
const formData = new FormData();
for (const i of Object.keys(this.images)) {
formData.append('images', this.images[i])
}
axios.post('/saveImage', formData, {
}).then((res) => {
console.log(res)
})
}
}

How to POST correctly a form that have data and files with VueJS, Axios and Laravel?

I am posting here as a beginner of VueJS and Laravel. I am stuck with a problem that I can't fix by myself after hours of search.
I would like to know how correctly send and get back the inputs of a form (complex data and files).
Here is the submit method of the form:
onSubmit: function () {
var formData = new FormData();
formData.append("data", this.model.data);
formData.append("partData", this.model.partData);
if (this.model.symbolFile != null) {
formData.append("symbolFile", this.model.symbolFile);
}
if (this.model.footprintFile != null) {
formData.append("footprintFile", this.model.footprintFile);
}
axios
.post("/api/updatecomponent", formData, {
headers: {
"Content-Type": "multipart/form-data",
},
})
.then((res) => {
// do something with res
// console.log(res);
})
.catch((err) => {
/* catch error*/
console.log(err);
});
},
The variable Data and PartData contains multiple string fields which will be stored in different tables in my database. Example :
Data
{
string Value,
string Tolerance,
string Power
}
Here is the method of the Controller in the server side:
public function updateComponent(Request $req)
{
$data = $req->input('data');
$partData = $req->input('partData');
$symbolFile = $req->file('symbolFile'); // is null if the user did not modify the symbol
$footprintFile = $req->file('symbolFile'); // is null if the user did not modify the footprint
// etc...
}
I am able to get the files, everything work for that and I can store and read them :)
But, the problem is that I am unable to get back properly my Data or PartDat.
When I do :
dd($partData);
I got as result in the console:
"[object Object]"
I am almost sure that I don't use correctly the FormData but after hours of search, I can't find the good way I should gave the Data and PartData to the FormData.
My code was working well for Data and PartData until I add FormData to support the file upload :(
Thank you for your help :)
Here my working code:
Client side:
var formData = new FormData(); // create FormData
formData.append("subcat", this.subcategory);// append simple type data
formData.append("data", JSON.stringify(this.model.data));// append complex type data
axios // send FormData
.post(url, formData, {
headers: {
"Content-Type": "multipart/form-data",
},
})
.then((res) => {
// do something with res
// console.log(res);
})
.catch((err) => {
/* catch error*/
console.log(err);
});
Server side:
public function createComponent(Request $req)
{
$subcategory = $req->input('subcat'); // get the input parameter named 'subcat' (selected subcategory)
$data = json_decode($req->input('data'), true); // get the input, decode the jason format, force to return the result as an array
}
I hope it will help other peoples :)
Simple solution
let data = new FormData();
data.append('image',file_name.value);
_.each(form_data, (value, key) => {
data.append(key, value)
})
console.log('form data',data);
Now you can get data in laravel controller like:
$request->title
$request->description
$request->file

Getting dynamic field data using vue.js in laravel

I am creating multiple dynamic fields and the same is posted to the laravel controller methods but i'm able to get the simple fields data (fields that are not dynamically generated) but the array fields that are dynamically generated those values i'm unable to get in the controller method.
<input :name="'students['+studentdetails.id+']['+studentdetails.class+']'" type="text" class="form-control"/>
<input :name="'students['+studentdetails.id+']['+studentdetails.class+']'" type="text" class="form-control"/>
In my controller method when i'm getting it:
printr($request->attributes);
export default {
data() {
...
return {
form: new Form({
title: "",
attributes: [],
}),
};
addStudent() {
const header = {
Authorization: "Bearer " + this.token,
};
this.form
.post(APP_URL + `/api/addStudent`, { headers: header })
.then((response) => {
if (response.status == 200) {
location.replace(APP_URL + "/success");
}
});
},
};
there is not value.
You are now creating [] and students as strings, and they should not be. Remove the string quotes completely, as you are using variables only:
:name="students[studentdetails.id][studentdetails.class]"

Vue 2, Cannot reference Prop Object in template

Problem: Although from the Vue DevTools I am passing the prop correctly and the router-view component has access to the data that it needs and in the correct format, whenever I try to access any of the data properties from within the template I get Uncaught TypeError: Cannot read property 'name' of null. It's really confusing because from the DevTools everything is a valid object and the properties are not null.
App.js
const game = new Vue({
el: '#game',
data: function() {
return {
meta: null,
empire: null,
planets: null
};
},
created: () => {
axios.get('/api/game').then(function (response) {
game.meta = response.data.meta;
game.empire = response.data.empire;
game.planets = response.data.planets;
});
},
router // router is in separate file but nothing special
});
main.blade.php
<router-view :meta="meta" :empire="empire" :planets="planets"></router-view>
script section of my Component.vue file
export default {
data: function() {
return {
}
},
props: {
meta: {
type: Object
},
empire: {
type: Object
},
planets: {
type: Array
}
}
}
Any ideas? Thanks in advance.
Because of your data is async loading so when my Component.vue renders your data in parent component may not be there. So you need to check if your data is loaded. You can try this code:
{{ meta != null && meta.name }}
PS: Your created hook should be:
created() {
axios.get('/api/game').then((response) => {
this.game.meta = response.data.meta;
this.game.empire = response.data.empire;
this.game.planets = response.data.planets;
});
},
router-view is a component from view-router which can help render named views. You can not pass empire and planets to it as those are props of your component.
You have to have following kind of code to pass empire and planets to your component:
<my-component :meta="meta" :empire="empire" :planets="planets"></my-component>
You can see more details around this here.

Resources