How I can upload a file using html input type "file" through ajax with web API model binder - asp.net-web-api

I'm using a MVC 5 web Api Controller, and I want my data coming through ajax with file to automatically bind?

You can append your uploaded file to FormData and send it via Fetch API.
Here's a demo to get started:
window.onload = () => {
document.querySelector('#myFile').addEventListener('change', (event) => {
// Just upload a single file, if you want multiple files then remove the [0]
if (!event.target.files[0]) {
alert('Please upload a file');
return;
}
const formData = new FormData();
formData.append('myFile', event.target.files[0]);
// Your REST API URL here
const url = "";
fetch(url, {
method: 'post',
body: formData
})
.then(resp => resp.json())
.then(data => alert('File uploaded successfully!'))
.catch(err => {
alert('Error while uploading file!');
});
});
};
<input id="myFile" type="file" />
After that just get the file from the current request in your API action method.
[HttpPost]
public IHttpActionResult UploadFile()
{
if (HttpContext.Current.Request.Files.Count > 0)
{
var file = HttpContext.Current.Request.Files[0];
if (file != null)
{
// Do something with file now
}
}
return Ok(new { message = "File uploaded successfully!" });
}

Related

Download link excel in vuejs

In controller laravel: I use box/spout , I save the excel file in a separate folder, and i create a variable that points to the folder where the file is saved, and i return the vuejs view to download that file
$path = '/files/'.$name;
$urlFile = url('/files/'.$name);
var_dump($urlFile);
// Result:
http://localhost.loca/file/data.xlsx
I return view vuejs:
return response()->json($urlFile);
View vuejs :
methods: {
// event button click
clickButton() {
axios
.get("/api/export")
.then((res) => {
console.log(res.data) // http://localhost.loca/file/data.xlsx
// I want to download this link !
})
.catch((error) => {
console.log(error);
});
}
}
Please give me idea download link ? Thanks
Update: I use window.open(res.data) but it doesn't work
Try to create an anchor and click on it programmatically to download the file :
.then((res) => {
console.log(res.data) // http://localhost.loca/file/data.xlsx
//create and append anchor download to body
const downloadAnchor = document.createElement("a");
downloadAnchor.setAttribute("href", "http://localhost.loca/file/data.xlsx");
downloadAnchor.setAttribute("download", "data.xlsx");
document.body.appendChild(downloadAnchor);
downloadAnchor.click();
//remove anchor download
document.body.removeChild(downloadAnchor);
})
If window.open doesn't work you can try this:
function download(url) {
const a = document.createElement('a')
a.href = url
a.download = url.split('/').pop()
document.body.appendChild(a)
a.click()
document.body.removeChild(a)
}
And then call the download function in your method:
methods: {
// event button click
clickButton() {
axios
.get("/api/export")
.then((res) => {
console.log(res.data) // http://localhost.loca/file/data.xlsx
download(res.data)
})
.catch((error) => {
console.log(error);
});
}
}

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

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

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

Add custom headers to upload image

I'm currently trying to integrate the CKeditor 5 ReactComponent into my app.
I'm facing an issue with the upload image functionality... I use a Node/Express backend which uses a JWT auth middleware, so each request must have an Authorization header in order to pass.
I want to know if one of the following is possible:
a way to add a custom header to the component
a way to overwrite the upload handler and call a custom handler instead in which I can do what ever
Below is my code
<CKEditor
editor={ClassicEditor}
data="<p>Add product description here</p>"
onInit={(editor) => {
// You can store the "editor" and use when it is needed.
//console.log('Editor is ready to use!', editor);
}}
onChange={(event, editor) => {
const data = editor.getData();
this.handleData(data)
}}
config={{
ckfinder: {
uploadUrl: `${apiUrl}/upload/images/description`,
},
}}
/>
Thanks
try it with this code in property onInit
onInit={ editor => {
editor.plugins.get( 'FileRepository' ).createUploadAdapter = function( loader ) {
return new UploadAdapter( loader );
};
}}
after you must create the class UploadAdapter
class UploadAdapter {
constructor( loader ) {
// Save Loader instance to update upload progress.
this.loader = loader;
}
upload() {
const data = new FormData();
data.append('typeOption', 'upload_image');
data.append('file', this.loader.file);
return new Promise((resolve, reject) => {
axios({
url: `${API}forums`,
method: 'post',
data,
headers: {
'Authorization': tokenCopyPaste()
},
withCredentials: true
}).then(res => {
console.log(res)
var resData = res.data;
resData.default = resData.url;
resolve(resData);
}).catch(error => {
console.log(error)
reject(error)
});
});
}
abort() {
// Reject promise returned from upload() method.
}
}

Resources