How to POST correctly a form that have data and files with VueJS, Axios and Laravel? - 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

Related

How I can extract, or save data from promise

people please help me with this.
I have an object, and I need to add some data to this object from json file.
let data = {
'test1':1,
'test2:2
}
function convert(){
fetch("./test.json")
.then(response => {
return response.json();
})
.then(jsondata => {
{data = {...data, ...jsondata}}
console.log(data)
});
}
console.log(data)
What I must to do in order to save new version data?
In your case, you just need to do this:
data = {...data, ...jsondata};
instead of this:
{data = {...data, ...jsondata}}

Get image from blob Laravel vue

First of all, this is the start of where I am at as a similar post
Store blob as a file in S3 with Laravel
I am sending a photo from VueJS to Laravel. It is coming as multipart/form-data.
Vue Code:
export default {
emits: ['onClose'],
props: ['isOpen'],
data: function() {
return {
serverOptions: {
process: (fieldName, file, metadata, load, error) => {
const formData = new FormData();
formData.append(fieldName, file, file.name);
axios({
method: "POST",
url: '/chat/room/upload',
data: formData,
headers: {
"Content-Type": "multipart/form-data"
}
})
.then(() => {
load();
})
.catch(() => {
error();
});
}
},
files: [],
};
},
methods: {
handleFilePondInit: function () {
console.log('FilePond has initialized');
// example of instance method call on pond reference
this.$refs.pond.getFiles();
console.log(this.$refs.pond.getFiles());
},
},
Laravel Controller:
public function uploadImage(Request $request)
{
// This is what this is SUPPOSED to do. Grab the file from the frontend
// Bring it here. Store it in S3, return the path with the CDN URL
// Then store that URL into the DB as a message. Once that is done, then
// Broadcast the message to said room.
if ($request->has('upload')) {
$files = $request->get('photo');
$urls = [];
foreach ($files as $file) {
$filename = 'files/' . $file['name'];
// Upload File to s3
Storage::disk('digitalocean')->put($filename, $file['blob']);
Storage::disk('digitalocean')->setVisibility($filename, 'public');
$url = Storage::disk('digitalocean')->url($filename);
$urls[] = $url;
}
return response()->json(['urls' => $urls]);
}
// broadcast(new NewChatMessage($newMessage))->toOthers();
// return $newMessage;
}
First: I want to state that if there is something wrong with the current code, just know its because ive been playing around with this for 3 hours now and been trying anything. I am sure at one point I had it close but somehow screwed it up along the way so I am more looking for fresh eyes to show me my error.
That being said, the other part to take into account is in DevTools under Network I can clearly see the blob and can load it up, I can also see the "upload" item and under there the form data which shows the following
------WebKitFormBoundary7qD7xdmiQO9U1Ko0
Content-Disposition: form-data; name="photo"; filename="6A8B48B4-F546-438E-852E-C24340525C20_1_201_a.jpeg"
Content-Type: image/jpeg
------WebKitFormBoundary7qD7xdmiQO9U1Ko0--
it clearly also shows photo: (binary) so I am completely confused as to what I am doing wrong. The ULTIMATE goal here is to get the image, store it as public in S3/DigitalOcean then grab the public URL to the file and store in the DB.
Any help would be GREATLY appreciated!

Form data sends empty request to the server

I am using vuejs and laravel to make a panel for admin
I understand i can not send any files without form data
so i gotta use formData like this
onSubmit(evt) {
evt.preventDefault();
this.emptyValidator();
let data = new FormData();
console.debug(this.form)
for (let input in this.form) {
data.append(input, this.form[input]);
}
data.append('image', this.image);
console.debug(data)
console.debug(this.image)
ProductDataService.update(this.id, data)
.then(response => {
let data = response.data;
if (data.data) {
Swal.fire('edited successfully', '', 'success');
}
})
.catch(error => {
if (error.response.status && error.response.status === 422)
this.handleValidation(error);
})
},
Note: i am using it in production mode
and when i try to dd in laravel it shows me empty
i did not have any problem with sending manual and formData in edit is a pain in my ass

ember.js `afterModel` event handler changes not reflected in Template

I have a route in which I use Ajax (not Ember Data) to pull a record, a costcentre, off the server. The record is intended to populate a template for subsequent edits.
Before the fetch, in beforeModel, an empty costcentre is created using createRecord. After the model processing is complete, in afterModel, the returned data is used to populate the costcentre object in the Data Store.
The fetch of the data is successful and in the debugger the update of the locally stored DS object can be seen to have worked but the changes are not seen in the template.
How can I get the template to populate with the data returned from the server ?
In the route I have this :
beforeModel: function(transition) {
this.set('ccToEdit', this.store.createRecord('costcentre'));
},
model(params) {
return getCCByCCIdent( this.urlbase,
this.currentMOP.currentMOP,
ENV.APP.MATClientCode,
params.cceIdentifier_to_edit);
},
afterModel(ccs, transition) {
//I'm testing this with an API end point that returns a
//list but there will only ever be one item in the list
this.ccToEdit.setProperties(ccs[0]);
},
The getCCByCCIdent looks like this :
export const getCCByCCIdent = function(urlbase, currentMOP, clientCode, targetCostCentreIdent) {
return new Promise(function (resolve, reject) {
if (targetCostCentreIdent.length == 0)
{
resolve([])
}
else
{
var theUrl = `${urlbase}/costcentres/${currentMOP}/${clientCode}/${targetCostCentreIdent}`;
$.ajax({
type: 'GET',
url: theUrl,
success: function (response) {
resolve(response);
},
error: function (request, textStatus, error) {
reject(error);
}
});
}
})
}
The simplest way to do this would be to do a then() on the promise being returned from your Ajax call, set appropriate values after that and then return your model:
model(params) {
return getCCByCCIdent(
this.urlbase,
this.currentMOP.currentMOP,
ENV.
params.cceIdentifier_to_edit
).then(ccs => {
let costCentre = this.store.createRecord('costcentre');
costCentre.setProperties(ccs[0]);
return costCentre;
});
},

Unable to read filelist object in Laravel controller from vue

I'm creating an application where user is filing up a form with possibility to send multiple files along
In vue.js I'm creating formData with an array of files and with an object with the rest of inputs fields. I'm posting that with Axios.
In request in Laravel controller I can't access my filelist-object.
I can see the
$request->My_Array,
but I can read the data store inside
I have tried to use loops also I have try :
$request->all();
$request->file('files');
My input
<input class="browse" V-on::change="onImageChange" type="file">
My vue.js component
onImageChange(event) {
this.files.push(event.target.files);
},
submit(e) {
e.preventDefault();
let currentObj = this;
const fd = new FormData();
for (let i = 0; i < this.files.length; i++) {
fd.append('IoFiles[]', this.files[i]);
}
console.log(this.files);
fd.append('IoFiles', this.files);
fd.append('fields', JSON.stringify(this.fields));
axios.post('/io',
fd,
{headers: {'Content-Type': 'multipart/form-data'}})
.then(function (response) {
currentObj.output = response.data;
})
.catch(function (error) {
currentObj.output = error;
});
},
My Laravel controller
public function store(Request $request)
{
if ($request->IoFiles) {
$medias = $request->IoFiles;
foreach ($medias as $image) {
return $image->getClientOriginalName();//That give me an error
}
}
}
There are a couple of issues with your code.
Firstly, V-on::change="onImageChange" should be:
v-on:change="onImageChange"
Please note:
the lowercase v for v-on
the single :
Alternatively, you could write #change="onImageChange".
Secondly, event.target.files returns a FileList not a single file so you need to change your onImageChange code to the following be able to get the file itself:
onImageChange(event) {
this.files.push(event.target.files[0]); //Note the [0] after files
},

Resources