axios/laravel/formdata post request is empty - laravel-5

I want to upload some files, but when i post with axios, my formdata is an empty request in laravel
vuejs: uploader.vue
filesChange(e) {
const fileList = e.target.files;
const formData = new FormData();
if (!fileList.length) return;
for (let i = 0; i < fileList.length; i += 1) {
console.log(fileList[i]);
formData.append('files', fileList[i], fileList[i].name);
}
this.save(formData);
},
output from console, all files are looped and appended to formData
save(formData) {
photosApi.storePhotos(formData, this.galleryId).then((response) => {
console.log(response);
}).catch((error) => {
console.log(error);
});
},
vuejs: photosApi.js
storePhotos(formData, id) {
return axios.post(`api/photo/${id}`, formData);
},
when i inspect my api-call i see this
laravel: api.php
Route::post('/photo/{id}', 'PhotoController#store');
laravel: PhotoController.php
public function store(Request $request, $id)
{
return $request->all();
}
the return of my response is only empty...
what im'doing wrong?

I solved it finally :)
the first problem was this line
formData.append('files', fileList[i], fileList[i].name);
append was always overwriting the last "files" entry... (i thought it was working like push)
so the first fix was
formData.append(`file${i}`, fileList[i], fileList[i].name);
to see the data don't use
return $request->all();
instead use
print_r($request->all());
now you can see something usefull when you inspect your apicall
now it was easy
$data = $request->all();
foreach ($data as $key => $file) {
$file->move('/public/images', $file->getClientOriginalName());
};
all my files are stored in my folder ;)
UPDATE:
I found out, if i write files with "[]" then i get also the data as an array
for (let i = 0; i < fileList.length; i += 1) {
formData.append('files[]', fileList[i], fileList[i].name);
}
And in my controller i get access to my files with this line, but without the "[]"
$files = $request->file('files');

Related

How to upload multiple images with base64 in laravel & vue-js

I have been trying to upload multiple images with base64 but it uploads only the second one.
and Is there any easy way to upload images in larvel-vueJS instead of base 64.
this is the Vue-js method:
updateIMG(e){
// console.log('uploaded');
let file = e.target.files[0]
let reader = new FileReader();
if(file['size'] < 9111775){
reader.onloadend = (file) => {
this.landingform.logo = reader.result;
this.landingform.landingBg = reader.result;
}
reader.readAsDataURL(file)
}else {
swal.fire({
icon: 'error',
title: 'Oops...',
text: 'You are uploading a large fiel!',
footer: 'You are authorized to upload files less than 10MB.'
})
}
the method called like this:
<input type="file" #change="updateIMG" name="logo" class="form-input">
and this is my controller:
public function updateLanding(Request $request)
{
$landnginIMG = LandingImage::whereIn('id', [1]);
if ($request->logo){
$name = time().'.' . explode('/', explode(':', substr($request->logo, 0,
strpos($request->logo, ';')))[1])[1];
\Image::make($request->logo)->save(public_path('img/landing/').$name);
$request->merge(['logo' => $name]);
};
if ($request->landingBg){
$bgname = time().'.' . explode('/', explode(':', substr($request->landingBg, 0,
strpos($request->landingBg, ';')))[1])[1];
\Image::make($request->landingBg)->save(public_path('img/landing/').$bgname);
$request->merge(['landingBg' => $bgname]);
};
$landnginIMG->update([
'logo'=> $request ['logo'],
'landingBg'=> $request ['landingBg'],
]);
return ['message' => 'all is done'];
}
There are a few factors your must follow.
First
Your form should let you select multiple files
Second
Your JavaScript must handle all of those files when selected. Check this line of your code.
// console.log('uploaded');
let file = e.target.files[0]
let reader = new FileReader();
e.target.files[0] is taking the first file. You should loop and go through all files.
let files = e.target.files;
Now, use JavaScript foreach loop and convert each file to base64 and store them on array. Then, send that array to sever.
On the server, do the same. You will receive an array so you should loop through each and convert it back to image and save it.
Thanks.
Pls check if this helps:
Vuejs example of multiple image upload https://picupload.netlify.app/
VueJS code repo https://github.com/manojkmishra/dw_take5
Concerned File- https://github.com/manojkmishra/dw_take5/blob/master/src/components/ImageUploader.vue
PHP[Laravel] part is behind firewall so upload submission will not work outside intranet. Here is the controller function code
public function imagesupload(Request $request){
if (count($request->images)) {
foreach ($request->images as $image) {
$image->store('images');
}
}
return response()->json(["message" => "Done"]);
}

want to update array values in vuejs using laravel

i have an array values in update form. i need to update specific values when user change in textareas. it looks like this
In my vuejs data objects looks like this.
data() {
return {
jobs: [],
details: {
basic_id: this.$route.params.id,
work: this.jobs
}
};
},
and my update method i wrote like this.
updateDetails() {
this.loading = true;
this.updateWorkedPlaces(this.details)
.then(() => {
console.log("success");
this.loading = false;
})
.catch(() => {
this.loading = false;
});
}
i pass these values it my vuex action methods.
async updateWorkedPlaces({ commit }, payload) {
let job = await Api().put("works/" + payload.basic_id, payload.work);
commit("UPDATE_WORK", job);
},
i pass these values to my laravel backend update function. it looks like this.
public function update(Request $request, $id)
{
$work = $request->work;
$basic = $request->basic_id;
foreach ($request->work as $i => $id) {
$job = Job::findOrFail($basic);
$job->fill(['position' => $id['position'], 'address' => $id['address']])->save();
}
return response()->json(['message' => 'success']);
}
but when i pass these values to this function it shows me this error.
Invalid argument supplied for foreach()
how can i fix this error. anyone can help me?
i figure out my problem with this function
public function update(Request $request, $id)
{
$collection = $request->all();
for ($i = 0; $i < count($collection); $i++) {
Job::where('id', $collection[$i]['id'])
->update([
'position' => $collection[$i]['position'],
'address' => $collection[$i]['address']
]);
}
return response()->json(['collection' => $collection]);
}

vuejs form data sent via api not visible on laravel controller

have a look
vuejs
data() {
return {
url: '/api/client/document/upload',
}
},
computed
attachment() {
return {
slug: 'testing',
test_type[enter image description here][1]: (this.individual === 1)? 'transfer_individual': 'transfer_corporate',
application_id: this.client_investment_id
};
upload method
upload: function () {
if(!this.validateForm()) {
Message.warning({ message: 'Complete the form and proceed' });
return;
}
if(!this.$refs.upload.uploadFiles[0]) {
Message.warning({ message: 'Upload the form and proceed' });
return;
}
console.log('data', this.attachment);
this.$refs.upload.submit();
},
controller side laravel
public function uploadDocument()
{
$input = request()->all();
dd($input);
}
there is a file am uploading to the given url;
when i dd from the controller i get an application_id of null but if i console.log before the submittion am able to view my data. what may i be doing wrong.
console.log output
dd output
Pass the request as parameter to the function and call the all() method on the request instance.
public function uploadDocument(Request $request)
{
$input = $request->all();
dd($input);
}
To take and save file with its name concatenated with a timestamp in public/images folder try
//Assuming you have the file input name as `photo`
if ($file = $request->file('photo')) {
$name = time() . $file->getClientOriginalName();
$file->move('images/', $name);
}
this is the form ...note its taking with it the attachment data from computed property..
<el-upload
class="upload-demo"
drag
:action=url
ref="upload"
:data=attachment
:headers="defaultHeaders"
:on-error="errorOnUpload"
:on-success="showUploadSuccess"
:accept=extensions
:thumbnail-mode="false"
:auto-upload="false">
</el-upload>
<el-button type="success" size="mini" #click="upload" class="el-icon-upload">upload</el-button>
i have noted that i set the application_id to be set to the store when client applies, but now am dealing with edit, its taking the default state of the application_id which is null

ajax routing with symfony

I am using symfony and twig and trying to route to a controller function that exists, using ajax. The route I am trying to get to seems to be appended to the current route (page) that is calling the ajax. What is causing this and what am I doing wrong? I am intermediate at this. Thanks in advance for your efforts.
The ajax looks like;
$.ajax({url: "{{ path('material-stock_check') }}/" + quoteRing.materialId + "/" + quoteRing.gaugeId + "/" + decimal, success: function (results) {
if (results.length === 0) {
quoteRing.findStripWidthAlternates();
}
}});
and the controller looks like
/**
* Check if the strip width is in the Inventory
* #Route("/check/{materialId}/{gaugeId}/{decimal}", defaults={"materialId" = 0, "gaugeId" = 0, "decimal" = 0}, name="material-stock_check")
* #Method("GET")
*/
public function checkStripWidthAction (Request $request, $materialId, $gaugeId, $decimal)
{
$em = $this->getDoctrine()->getManager();
$materialStocks = $em->getRepository('UniflyteBundle:MaterialStock')->findAllByParams(['widthDecimal' => $decimal, 'materialId' => $materialId, 'gaugeId' => $gaugeId]);
if ($request->isXmlHttpRequest()) {
if (null === $materialStocks) {
return new JsonResponse('failure');
}
$results = [];
foreach ($materialStocks as $result) {
$results[] = [
'gaugeId' => $result->getGauge()->getId(),
'materialId' => $result->getMaterial()->getId()
];
}
return new JsonResponse($results);
}
}
When the ajax is called I am getting
No route found for "GET /uniflyte/quote-ring/new/%7B%7B%20path('material-stock_check')%20%7D%7D/93/347/3.45" (from "http://localhost:8088/uniflyte/quote-ring/new/rolled-ring")
The ajax route looks appended to the existing route. What am I doing wrong?
It seems {{ path(...) }} is not being evaluated by twig as #Omar Alves told.
try this, declare a variable in your twig file
<script>
var url = '{{ path("material-stock_check") }}';
</script>
and then use it
Have you declare the path in route file

Proper way of sending json response

I used to write in the controller method:
echo json_encode(TRUE);die;
to pass the success message to the AJAX so that.
e.g.
if($user->save())
{
echo json_encode(TRUE);die;
}
and in ajax:
success: function (data) {
var res = $.parseJSON(data);
if(res == true)
{
alert('user added!');
}
But then i saw most using:
return Response::json(TRUE); die; instead of echo json_encode(TRUE);die; what is the difference between these two? Or is it exact similar to echo vs return?
If you just echo text, your response will be sent back the the content type of plain/html.
If you return response()->json(), then your response will be sent back with the content type of application/json.
Some clients may not care one way or another, but others may behave differently if the headers say the response is json. In either case, the application/json response is more semantically correct.
I recomend you to echo the result of a function. For example:
function save(){
//magic happens here
return $result; //can be false or true (for example)
}
and in the file which is called in the ajax request simply put:
echo json_encode(save());
finally you can compare the result in the client side:
success: function(response){
var result = $.parseJSON(response);
if(result) alert("Success!");
else alert("Sorry try later");
}
This is how I have done and it's very standard. I have create one helpers.php file and put it in composer.json so no need to further include it in application.
composer.json
"autoload": {
"files": [
"app/Utils/helper.php"
]
}
run command
composer dumpautoload.
Create method for success response in helpers.php
function success($data, $message, $status = 200, $headers = [])
{
$result = [];
$result['flag'] = true;
$result['message'] = $message;
$result['data'] = $data;
return response()->json($result, $status, $headers);
}
sending success message from controller.
return success($user, 'User logged in successfully.');
Create method for error response in helpers.php
function error($code, $message, $status = 200, $errors = [], $headers = [])
{
$error = [];
$error['flag'] = false;
$error['message'] = $message;
$error['code'] = $code;
if (!empty($errors))
{
$error['errors'] = $errors;
}
return response()->json($error, $status, $headers);
}
sending error message from controller.
return error(401, 'These credentials do not match our records.',401);

Resources