Upload File, file path null, VueJs / Laravel - laravel

I try to create a simple file upload with Vuejs and Laravel. But my 'file' variable it seems to be null on post.
<b-form-group label-for="file">
<b-form-file
v-model="file"
id="file"
:state="Boolean(file)">
</b-form-file>
</b-form-group>
data() {
return {
file: null,
},
}
and a method for post . (that works for the rest of the form)
addContract(newContract) {
post("/contracts/" + `${this.customer_id}`, newContract)
.then((response) => {
//
}
.catch(error){
//
}
}
Controller
//code
$fileName = time(). '.' .$request->$file->getClientOriginalExtention();
$request->file->move(public_path('upload'), $fileName);
dd($fileName);
//code
UPDATE
I set the axios header, but now I got error 422, when it was application I didn't but it still didn't work.
headers: {
'Content-Type': 'multipart/form-data'
}

In order for the file to upload via native browser submit, you must provide a name for the file input (along with adding enctype="multipart/form-data" to the enclosing <form> element).
<b-form-file
v-model="file"
id="file"
name="file"
:state="Boolean(file)">
</b-form-file>
This is the same requirement for any form <input>, <select>, or <textarea> control.

Related

How to send by form an image in http request, and with what headers?

I searched on google and nothing...
i have a form in my view on vueJS :
<form #submit.prevent="avatar()" method="POST" enctype="multipart/form-data">
<input type="file" name="profilePicture" id="profilepicture" >
<button type="submit">Valider mon avatar?</button>
</form>
The user send an image.
My question is,
i want to send the image (sending by user with the form) in a function, and this function send the image to Http Request in headers ...
the api request begin with :
app.post('/myupload/:iduser', async (req, res) => {
try{
var { iduser } = req.params ;
const { image } = req.file ;
[...]
my function in my view on vuejs is actually :
async function avatar() {
console.log(document.getElementById("profilepicture").value);
// for having the image sending src
let response = await fetch(`http://localhost:196/myupload/${MyTokenStore.myid}`, {
method: "POST",
headers: {
"Content-Type": "multipart/form-data",
},
body: JSON.stringify(document.getElementById("profilepicture").value)
})
.then((response) => response.json())
.catch((error) => {
console.log("Failed", error)
});
if(response.error){
alert(response.message);
return
}
}
But the only parameter i make in request is the string of the src image, and the error servor is :
TypeError: Cannot destructure property 'image' of 'req.files' as it is undefined.
Please, i need help, the request run when I go directly to the url of the request (but the browser directly displays the server response):
<form :action="`http://localhost:196/myupload/${MyTokenStore.myid}`"
method="POST" enctype="multipart/form-data">
<input type="file" name="image"/>
<button type="submit">Valider mon avatar</button>
</form>
but I fail to put it in a function...
thank you.
To send an image from Vue doing a request you have to use a FormData object. For example:
/**
* #description - register user
*/
const register = async () => {
try {
const fd = new FormData();
Object.keys(user.value).forEach((key) => {
fd.append(key, user.value[key]);
});
const res = await axios.post('/register', fd, {
headers: {
'Content-Type': 'multipart/form-data',
},
});
toast.success(res.data);
} catch (err) {
console.log(err);
toast.error(err.response.data);
}
};
In the previous code, in register I'm using a FormData to send the user object to the backend. Previously, you should set it. I made it like the following example:
const setProfileImage = (e) => {
image_preview.value = URL.createObjectURL(e.target.files[0]);
document.getElementById('image_preview').style.height = '150px';
document.getElementById('image_preview').style.width = '150px';
user.value.profile_image = e.target.files[0]; // this is important for you.
user.value.image = e.target.files[0].name;
};
setProfileImage is receiving an event from an Input file. If you see the comment I write in the code, user.value.profile_image = e.target.files[0] is the entire file. The rest is to display the image and send the name to store into the database.
<div class="mb-3">
<label
for="profile_image"
class="bg-primary text-white rounded-3 text-center w-100 p-2 profile_image"
>
Seleccione su foto de perfil <i class="ps-1 bi bi-card-image"></i>
</label>
<input
type="file"
class="form-control d-none"
id="profile_image"
placeholder="Adjunte su foto de perfil"
#change="setProfileImage"
/>
</div>
This is the Input file what I was talking. The event is an #change to catch correctly the file.
Hope it works for you.

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)
})
}
}

Unable to upload a file using Vue frontend and laravel server

I am trying to upload a file (File can be anything i.e. an image or pdf or doc, absolutely anything) . For that, I made a test form into my Vue component that is below
<form class="mt-5" method="post" enctype="multipart/form-data" id="uploadForm">
<div class="form-group">
<input type="file" id="test" name="test" class="form-control">
</div>
<button #click.prevent="uploadFile" type="button" class="btn btn-sm btn-primary">Upload</button>
</form>
Now when I submit form (click the upload button), I am running a function below
uploadFile() {
let something = $('#test').prop('files')[0];
console.log(something);
let form_data = new FormData();
form_data.append('file', something);
console.log(form_data);
axios.post('/upload/file', { form_data })
.then(() => {
console.log("done");
})
},
So when I console.log(something), it shows me the info of uploaded file but when I send data to server using axios and dd($request->all()) there, it shows me something => [] an empty array, that means, I am not getting the file and hence cant process it further to save it into my folders (upload).
What am I doing wrong here?
This happens because you are not setting the header Content-Type as multipart/form-data (and by default the application/json is being used) when making the request with axios, and the enctype attribute has no effect, since your not using the default form submit action. So try to pass a third argument in the post method, specifying the correct Content-Type header.
const uploadAvatar = ({ id, file }) => {
const formData = new FormData();
formData.append('avatar', file);
return axios.post(`users/${id}/avatar`, formData, {
headers: { 'Content-Type': 'multipart/form-data' },
});
};

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

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.

ASP.NET MVC 3 - File upload through AngularJS

I'm using AngularJS with my pages, and I have a doubt: when I do post with my form, how can I pass some selected file to my ASP.NET MVC 3 Controller?
Check this out:
My form:
<form enctype="multipart/form-data" ng-controller="FilesController" ng-submit="submitingForm()">
<div>
Choose the file:
<input type="file" onchange="angular.element(this).scope().setSelectedFile(this)" />
</div>
<input type="submit" value="Confirm" />
</form>
And the AngularJS Controller:
var module = angular.module('application', []);
(function (ang, app) {
function FilesController($scope, $http) {
$scope.setSelectedFile = function (element) {
$scope.$apply(function($scope) {
$scope.selectedFile = element.files[0];
});
};
$scope.submitingForm = function() {
$http.post(url, ???????).success(function() {
// How to pass that selected file for my ASP.NET controller?
});
}
}
app.controller("FilesController", FilesController);
})(angular, module);
Thank you!!!
I am not quite familiar with AngularJS but if you are attempting to upload a file using an AJAX request you can forget about it. That's not something that could be done. You could use the HTML5 File API if you want to upload files asynchronously to the server. There's an entire section dedicated to this.
And if your client browsers do not support the HTML5 File API you could use a File Upload plugin such as FineUploader or Uploadify (there are quite many others, just google).
My Approach is to use FormData.
Create a input tag like this.
<input id="imgInp" type="file" aria-label="Add photos to your post" class="upload" name="file" onchange="angular.element(this).scope().LoadFileData(this.files)" multiple="" accept="image/*" style="margin-top: -38px; opacity: 0; width: 28px;">
And in your Angular Controller create a method LoadFileData(inputFiles) as bellow:
var formData = new FormData();
$scope.LoadFileData = function (files) {
for (var file in files) {
formData.append("file", files[file]);
}
};
Now in formData variable you will have the uploaded files. Just send it to asp.net mvc controller.
$scope.submit = function () {
$http.post("/YourController/Method", formData, {
withCredentials: true,
headers: { 'Content-Type': undefined },
transformRequest: angular.identity
}).success(function (response) {
}
In Server side, Asp.NET MVC 4 controller you will have the files
var files = Request.Files;

Resources