How to upload files with Vue.js2 and Laravel 5.4? - javascript

I'm trying to upload an image using Laravel as a backend and Vue.js2 as a frontend.
Here's my code
addUser() {
let formData = new FormData();
formData.append('fullname', this.newUser.fullname);
formData.append('email', this.newUser.email);
formData.append('phone', this.newUser.phone);
formData.append('photo', this.newUser.photo);
formData.append('roles', this.newUser.roles);
formData.append('permissions', this.newUser.permissions);
axios.post('users', formData)
.then((response) => {
console.log(response);
})
.catch((error) => {
console.log(error);
});
},
onFileChange(e) {
let files = e.target.files || e.dataTransfer.files;
if (!files.length)
return;
this.createImage(files[0]);
},
createImage(file) {
let reader = new FileReader();
let vm = this;
reader.onload = (e) => {
vm.newUser.photo = e.target.result;
};
reader.readAsDataURL(file);
},
And Laravel code on a backend:
if($request->hasFile('photo')) {
return response()->json([
'success' => true,
'message' => 'Файл есть.',
'data' => $request->all()
]);
}
return response()->json([
'success' => true
]);
Finally, the html code:
<input type="file" class="filestyle" data-text="Загрузите фото" #change="onFileChange">
Unfortunately, it doesn't seem to work. File has not been found. What's the workaround?

I doubt that the image gets attached to the request sent because the line formData.append('photo', this.newUser.photo); only appends the file's temporary url to the formData due to the fact that the property photo of the newUser object was set to the temporary url of the file inside your FileReader onload method: vm.newUser.photo = e.target.result;.
You should attach the file to the formData and not the temporary url
To do that, you might want to change your createImage(file) function to:
createImage(file) {
let reader = new FileReader();
this.newUser.photo = file;
let vm = this;
reader.onload = (e) => {
vm.newUser.photo_preview = e.target.result;
};
reader.readAsDataURL(file);
},
and you can use this.newUser.photo_preview for showing the photo preview wherever you like in your view.
Hope that helps :)

Solved
I simply deleted createImage(file) method and changed onFileChange(e) method like this:
onFileChange(e) {
let files = e.target.files || e.dataTransfer.files;
if (!files.length)
return;
this.newUser.photo = files[0];
}
And everything worked perfecly. Thanks for everyone for spending time and help...)

Related

Getting fromData after async for loop

I am using two function two handle multiple files upload in ReactJS.
const doSomethingAsync = (file, formD)=>{
return new Promise((resolve) =>{
const type = file.type.split("/")[0];
const filename = file.name;
// file reader to preview file
let reader = new FileReader();
reader.onload = () => {
formD.append("fileList", file, filename);
setSelectedFileForUpload((prevState) => [
...prevState,
{
file: reader.result,
type: type,
name: filename,
},
]);
};
reader.readAsDataURL(file);
});
}
const handleFileUpload = (e) => {
const files = e.target.files;
if (!files) return false;
let formD = new FormData();
console.log("START");
for (const file of files) {
console.log("MID");
doSomethingAsync(file,formD);
}
console.log("END");
for (const file of formD) {
console.log(file); // not getting file. Don't know why.
}
};
If I use want to upload two files (or one file). Then
OUTPUT (if we upload two files) :
START
MID
MID
END
As you can see I am looping through formData by using :
for (const file of formD) {
console.log(file); // not getting file. Don't know why.
}
But it is NOT executing (may be because of length is 0).
So I want to get formData after for of loop completed.

How can I read the data in the excel file with reactjs or javascript using the path to the file

I want to read the contents of the file directly by using the file path. I can do this by having the file selected. But I don't know how to do it using the direct file path. I could not find any examples or sources for this. Below is how I read the file by selecting it from the input.
import * as XLSX from 'xlsx';
var items = [];
readExcel = (file) => {
const promise = new Promise((resolve, reject) => {
const fileReader = new FileReader();
fileReader.readAsArrayBuffer(file);
fileReader.onload = (e) => {
const bufferArray = e.target.result;
const wb = XLSX.read(bufferArray, { type: "buffer" });
const wsname = wb.SheetNames[0];
const ws = wb.Sheets[wsname];
const data = XLSX.utils.sheet_to_json(ws);
resolve(data);
};
fileReader.onerror = (error) => {
reject(error);
};
});
promise.then((d) => {
this.items = d;
console.log(this.items)
// fill dictionary
this.dictionary = Object.assign({}, ...this.items.map((x) => ({ [x.PartNumber]: x.Cost })));
console.log(this.dictionary)
});
};
<input
type="file"
onChange={(e) => {
const file = e.target.files[0];
this.readExcel(file);
}}
/>
I beleive it should work:
const req = new XMLHttpRequest();
req.responseType = "arraybuffer";
req.open("GET", "https://.../MyExcelFile.xlsx", true);
req.onload = () => {
const bufferArray = req.response;
const wb = XLSX.read(bufferArray, { type: "buffer" });
...
I couldn't find a direct read operation. I converted the excel file to json format and got my job done.

heic2any with file input

I can't get it to work for me with input file. I understand that this code uses fetch and should transform file to fetch but I have no idea.
heic2any:
fetch("https://alexcorvi.github.io/heic2any/demo/1.heic")
.then((res) => res.blob())
.then((blob) => heic2any({
blob,
toType:"image/jpeg",
quality: 0.7
}))
.then((conversionResult) => {
var reader = new window.FileReader();
reader.readAsDataURL(conversionResult);
reader.onloadend = function () {
base64data = reader.result;
console.log(base64data);
document.getElementById("target2").innerHTML = '<a download="image.webp" href="'+base64data+'">Download</a>';
}
})
.catch((e) => {
console.log(e);
});
input file:
<input id="image-file" type="file" onchange="SavePhoto(this)" >
<script><!-- comment -->
function SavePhoto(f)
{
let photo = f.files[0];
}
</script>
This is assuming you have the heic2any node module installed. If you don't you can install it with
npm install heic2any
Blob is one of the object properties and should be 'blob: photo' instead of just blob. Fetch is not necessary if you already have the file from the file input.
function SavePhoto(f) {
let photo = f.files[0];
heic2any({
blob: photo,
toType: 'image/jpeg',
quality: 0.7
}).then(blob => {
//use the converted blob to do whatever
//maybe let newFile = new File(blob, fileName.jpg, { type: 'image/jpeg' }) or something
}, error => {
//handle errors
});
}

Cordova plugin file not returning file from fileEntry

here is my code:
window.resolveLocalFileSystemURL(cameraCallback, (fileEntry) => {
this.teste1 = fileEntry
fileEntry.file(function (file) {
this.teste2 = file
let reader = new FileReader()
reader.onloadend = function (e) {
this.teste3 = this.result
}
reader.readAsDataURL(file)
})
}, (error) => {
this.teste4 = error
})
where cameraCallback is a "file:///path/to/file" image, which exists.
I want to read this image as a file, but this.teste2 is returning empty.
this.teste3 also returns empty.
Here is my filyEntry:
File Entry { "isFile": true, "isDirectory": false, "name":
"1558418616412.jpg", "fullPath":
"/Android/data/org.cordova.quasar.app/cache/1558418616412.jpg",
"filesystem": "", "nativeURL":
"file:///storage/emulated/0/Android/data/org.cordova.quasar.app/cache/1558418616412.jpg"
}
How can i solve this?
I tried many combinations of response, changing the reader function (e), is it a async problem? Didn't get any response to this, any example.
How can i read my fileEntry as a blob/file/base64 image?
Have you tried
let self = this
window.resolveLocalFileSystemURL(cameraCallback, (fileEntry) => {
 self.teste1 = fileEntry
 fileEntry.file(function (file) {
   self.teste2 = file
   let reader = new FileReader()
   reader.onloadend = function (e) {
     self.teste3 = self.result
   }
   reader.readAsDataURL(file)
 })
}, (error) => {
 self.teste4 = error
})

What is the correct fetch body in React with FileReader

I have a React app which gets data from an upload. I want to send the data (mostly CSV's) row by row to my API. The problem is that I cannot get the correct value.
const uploadLocalFile = (file) => (dispatch) => {
const reader = new FileReader()
reader.onload = evt => {
fetch("some/api/here",
{
credentials: "same-origin",
method: "POST",
body: //file, evt.target.result ?? <---
})
}
reader.readAsText(file)
alert("done.")
}
file is the whole file, evt.target.result is not allowed in react? Is evt.currentTarget forbidden by fetch?
What do you mean by "not allowed in react"? Passing this function as the handler for your file input should work:
handleSelectFile = (event) => {
const file = event.currentTarget.files[0]
const reader = new FileReader()
reader.onload = (event) => {
const content = event.target.result
// do whatever you want do do with `content`
}
reader.readAsText(file)
}

Categories

Resources