how to get the path of an uploaded file in reactjs.
I use the file upload to upload a file
render() {
return (
<div>
<input type="file" onChange={this.fileChangedHandler} />
<button onClick={this.uploadHandler}>Upload!</button>
</div>
)
}
then bind the uploadHandler
this.uploadHandler = this.uploadHandler.bind(this)
and
uploadHandler = () => {
console.log("the selected file is : "+this.state.selectedFile.name)
}
Here I'm getting its name. I want to get the file path.
If you want to upload an image without posting to a server, you can use base64.
reactjs:
this.state = {
imgUpload: '',
}
...
this.getBase64 = this.getBase64.bind(this)
...
getBase64(e) {
var file = e.target.files[0]
let reader = new FileReader()
reader.readAsDataURL(file)
reader.onload = () => {
this.setState({
imgUpload: reader.result
})
};
reader.onerror = function (error) {
console.log('Error: ', error);
}
}
...
<div>
<input type="file" className="input-file" name="imgUpload" accept='.png' onChange={this.getBase64} />
</div>
Then you can use {this.state.imgUpload} to access the base64 string and can manipulate the image.
Related
I have this code from firebase documentation on my firebase file
export async function deleteImage(docId){
// Create a reference to the file to delete
const desertRef = ref(storage, `images/${docId}`);
await deleteObject(desertRef).then(() => {
swal("GOOD", "success");
}).catch((error) => {
swal("error!", "error");});
}
➡️ And i have this code for upload and download URL image on my Dashboard View
async function handleOnChangeProfileImage(e) {
console.log(e.target);
setLoading(true) // Setloading to true
var fileList = e.target.files;
var fileReader = new FileReader();
if (fileReader && fileList && fileList.length > 0) {
fileReader.readAsArrayBuffer(fileList[0]);
fileReader.onload = async function () {
var imageData = fileReader.result;
const res = await setUserProfilePhoto(currentUser.uid, imageData);
if (res) {
const tmpUser = { ...currentUser };
tmpUser.profilePicture = res.metadata.fullPath;
setCurrentUser({ ...tmpUser });
await updateUser(tmpUser);
const url = await getProfilePhotoUrl(currentUser.profilePicture);
setProfileUrl(url);
//updateUserProfilePhoto(currentUser.uid, res.fullPath);
}
};
}
}
➡️ And this is in html
<img className="mb-3 lazyload" key={profileUrl} srcSet={profileUrl} data-src={userImg}
width={200} alt="web.app" />
<Button onClick={handleOpenFilePicker} variant="primary"><FontAwesomeIcon icon={faUpload} /> Upload</Button>
<Button onClick={deleteImage} variant="danger"><FontAwesomeIcon icon={faDeleteLeft}/> Delete</Button>
I can upload an image successfully, but i want to delete the user's profile image with a OnClick event, and for that I use his docId as a reference, but the result is negative, what else do I have to create or do to delete the uploaded image? Hope you help me!! Thanks a lot!
I'm working on a problem where I have to take three images as input from the user and have to send them to the backend by converting them into Base64. I know how to do it for a single input file but can't work my way around for multiple inputs.
I want to have a single function that can convert the images to Base64 & store the value of each image in a separate variable. Please help me out with this.
Following is the code I'm using for single input i.e. First Image.
HTML CODE
<div class="first_div">
<label for="first_image">First Image</label>
<input name="first_image" type="file" accept="image/*" id="first_image" class="img_file">
</div>
<div class="second_div">
<label for="second_image">Second Image</label>
<input name="second_image" type="file" accept="image/*" id="second_image" class="img_file">
</div>
<div class="third_div">
<label for="third_image">Third Image</label>
<input name="third_image" type="file" accept="image/*" id="third_image" class="img_file">
</div>
<button onclick="submitImages()">Submit</button>
JAVASCRIPT CODE
let encoded_image;
function getBase64(file) {
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function () {
console.log(reader.result);
encoded_image = reader.result;
};
reader.onerror = function (error) {
console.log('Error: ', error);
};
}
const submitImages = () => {
var files = document.getElementById('first_image').files[0];
if (files.length > 0) {
getBase64(files[0]);
}
const formData = new URLSearchParams(new FormData());
formData.append("first_image", encoded_image);
fetch(API CALL HERE)
}
I want to create a function that takes input from all three fields, converts them to Base64 & stores in a variable. So that I can append it to form data.
Select all inputs, loop and get base64 of each file
Try this
const getBase64 = (file) =>
new Promise((resolve, reject) => {
console.log(file);
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result);
reader.onerror = (err) => reject(err);
});
const submitImages = async () => {
const imageInputs = document.querySelectorAll("input");
const images = await Promise.all(
[...imageInputs].map((imageInput) =>
imageInput?.files?.[0] ? getBase64(imageInput.files[0]) : null
)
);
console.log(images);
};
This example is in React but you can easily modify it to standard javascript.
If it's standard javascript just change const [images, setImages] = useState([]); into let images = [].
const [images, setImages] = useState([]);
const formatImage = async() => {
try {
for (let i = 0; i < e.target.files.length; i++) {
const reader = new FileReader();
reader.readAsDataURL(e.target.files[i]);
reader.onload = (readerEvent) => {
images.push(readerEvent.target ? .result);
};
}
} catch (error) {
console.log(error);
}
};
<input type="file" multiple onChange={formatImage} />
And here is an example of putting these images on Firebase Firestore and again if it's standard javascript change setImages([]) to images = []
const addImage = async() => {
try {
Promise.all(
images.map(
async(file: any) =>
await addDoc(collection(db, "images"), {
image: file,
date: Timestamp.now(),
})
)
);
setImages([]);
} catch (error) {
console.log(error);
}
};
I'm using Vue with Laravel and I tried to do a simple crud which is working good regarding things like title or description of an article (text-fields) but when I try to send an image file, it doesn't work. I have tried formData but to no avail.
This is my form in template, title goes in the database with no problem, if I console log selectedFile then it shows the file selected correctly but the addArticle method not attaching the images
<form #submit.prevent="addArticle" class="container">
<label>Title</label>
<input type="text" v-model="article.title" />
<label>Image</label>
<input type="file" v-on:change="selectedFile" />
<button type="submit">Create</button>
</form>
This is my script
<script>
export default {
data() {
return {
fileSelected: null,
article: {},
};
},
methods: {
addArticle() {
var formData =new FormData();
formData.append(this.article.image, this.fileSelected);
axios
.post("http://localhost:8000/api/articles", this.article)
.then((response) => this.$router.push({ name: "ArticlesList" }))
.catch((err) => console.log(err))
.finally(() => (this.loading = false));
}
,
selectedFile(event) {
this.fileSelected = event.target.files[0];
},
},
};
</script>
this is my code
<input type="file" #change="onFileChange">
onFileChange(e) {
this.sendphoto = e.target.files[0];
},
editUser() {
var self = this;
let formData = new FormData();
formData.append("image" , self.sendphoto )
let config = {
header : {
'Content-Type' : 'multipart/form-data'
}
}
axios.post('/edit-user' , formData , config)
.then(function (response) {
})
.catch(function (error) {
console.log(error);
})
},
You are creating a FormData object but you are not sending it within your Axios request.
In order to send the file and form data, you have to append everything to FormData object.
<script>
export default {
data() {
return {
fileSelected: null,
article: {},
};
},
methods: {
addArticle() {
var formData =new FormData();
formData.append('image', this.fileSelected);
formData.append('title', this.article.title);
axios
.post("http://localhost:8000/api/articles", formData)
.then((response) => this.$router.push({ name: "ArticlesList" }))
.catch((err) => console.log(err))
.finally(() => (this.loading = false));
}
,
selectedFile(event) {
this.fileSelected = event.target.files[0];
},
},
};
</script>
this worked in sending image files as string on database, hopefully it helps other people that are having similar problems
setup() {
const base64 = ref()
const changeFile= async(event) => {
const file = event.target.files[0];
base64.value = await convertBase64(file);
}
const convertBase64 = (file) => {
return new Promise ((resolve, reject) => {
const fileReader = new FileReader();
fileReader.readAsDataURL(file);
fileReader.onload = () => {
resolve(fileReader.result)
}
fileReader.onerror = (error) => {
reject(error)
}
})
}
const form = reactive({
title: " ",
body: " ",
image: base64,
})
const submitForm = () => {
axios.post("http://localhost:8000/api/articles", form)
}
return { changeFile, submitForm, form}
},
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
});
}
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...)