Cannot get attribute size from File object in React - javascript

With input is file, I can log to console the File as
console.log(file.size)
It gives me:
File(3987) {name: "download.jpeg", lastModified: 1544914267262, lastModifiedDate: Sat Dec 15 2018 14:51:07 GMT-0800 (Pacific Standard Time), webkitRelativePath: "", size: 3987, …}
lastModified: 1544914267262
lastModifiedDate: Sat Dec 15 2018 14:51:07 GMT-0800 (Pacific Standard Time) {}
name: "download.jpeg"
size: 3987
type: "image/jpeg"
webkitRelativePath: ""
__proto__: File
However when I do console.log(e.target.files[0].size)
It does not even fire.
Full Code as requested. FIle is coming from <input onChange={(e)=>{this.handChangeFile(e.target.files[0])}}/>
this.handleChangeFile = (file) => {
console.log(typeof file)
this.setState({ thefile: file })
let fileData = new FileReader();
fileData.readAsDataURL(file);
fileData.onloadend = () => {
imageBase64 = fileData.result
if (this.state.first == true) {
this.setState({ binary: imageBase64, hide_stock: !this.state.hide_stock, first: false }, () => {
})
}
else
this.setState({ binary: imageBase64 }, () => {
})
}
}

This is my solution on jsfiddle
with jQuery: https://jsfiddle.net/huynhsamha/dqLv83zr/
with React: https://jsfiddle.net/huynhsamha/23fv1te5/
Both they are working. Can you share your code why it is not working?
jQuery
<script async src="//jsfiddle.net/huynhsamha/dqLv83zr/embed/js,html,css,result/dark/"></script>
React
<script async src="//jsfiddle.net/huynhsamha/23fv1te5/embed/js,html,css,result/dark/"></script>

Related

How to pass a File JS object to Rails controller

I have a JS file object (like the one below) that I'd like to pass to my rails controller.
File {name: 'undefined', lastModified: 1652457009460, lastModifiedDate: Fri May 13 2022 10:50:09 GMT-0500 (Central Daylight Time), webkitRelativePath: '', size: 582843, …}lastModified: 1652457009460lastModifiedDate: Fri May 13 2022 10:50:09 GMT-0500 (Central Daylight Time) {}name: "undefined"size: 582843type: "image/png"webkitRelativePath: ""[[Prototype]]: FilelastModified: (...)lastModifiedDate: (...)name: (...)webkitRelativePath: (...)constructor: ƒ File()Symbol(Symbol.toStringTag): "File"size: (...)type: (...)get lastModified: ƒ lastModified()get lastModifiedDate: ƒ lastModifiedDate()get name: ƒ name()get webkitRelativePath: ƒ webkitRelativePath()[[Prototype]]: Blob
I'm trying to pass it inside a data object like this:
data: { someData: '', myFile: JSON.stringify(myFile)}
Unfortunately that results in passing an empty object like below:
data: { someData: '', myFile: {}}
If I try to pass it without stringifying it I get:
serialize.js:66 Uncaught TypeError: Illegal invocation
The only way I've been able to do it is via FormData() like:
const formData = new FormData(); formData.append("file", myFile);
However, I cannot use formData in this occasion for other reasons.
Can you provide some guidance on what other ways are there to pass this data?

react axios request object is not being sent to the backend controller properly. sending empty object

I have a react project and I am trying to get photo upload and storing to work. I currently have a form where the users uploads a profile picture. When the profile picture is uploaded, the entire file object is sent with the axios request from the react frontend to sequelize backend. I am running into the issue where the entire file object is being sent in the request body, but when I console.log in the controller... it is showing an empty object rather than the file object I know I am sending from the frontend to the backend.
I have no idea why all the data is being lost.
Here is the react function that is sending the axios request:
function createProfile(userId){
console.log('about to create profile with picture')
console.log(profilePicture)
axios.post('/api/profile/', {
'profile_pic':profilePicture,
'f_name':firstName,
'l_name':lastName,
'bio':bio,
'location':location,
'sm_facebook':facebook,
'sm_instagram':instagram,
'sm_twitter':twitter,
'sm_website':website,
'followers':0,
'following':0,
'photos':0,
'edits':0,
'downloads':0,
'userId':userId
})
.then((data) => {
return(<Navigate to='/' />)
})
.catch((err) => {
console.error(err)
})
}
the console.log(profilePicture) is displaying the following:
File {name: 'pexels-any-lane-5946095.jpg', lastModified: 1638937909688, lastModifiedDate: Tue Dec 07 2021 20:31:49 GMT-0800 (Pacific Standard Time), webkitRelativePath: '', size: 504333, …}
lastModified: 1638937909688
lastModifiedDate: Tue Dec 07 2021 20:31:49 GMT-0800 (Pacific Standard Time) {}
name: "pexels-any-lane-5946095.jpg"
size: 504333
type: "image/jpeg"
webkitRelativePath: ""
[[Prototype]]: File
Here is the backend controller:
post:(req, res) => {
const dirPath = '/Users/omarjandali/dev/fotos-web/backend/client/static/images/ProfilePictures'
console.log(__dirname)
console.log(req.body)
let body = req.body
Profile.create({
profile_pic: "diller",
f_name: body.f_name,
l_name: body.l_name,
bio: body.bio,
location: body.location,
sm_facebook: body.sm_facebook,
sm_instagram: body.sm_instagram,
sm_twitter: body.sm_twitter,
sm_website: body.sm_website,
followers: body.followers,
following: body.following,
photos: body.photos,
downloads: body.downloads,
edits: body.edits,
userId: body.userId
})
.then((data) => {
res.send(data).status(200)
})
.catch((err) => {
console.error(err)
res.send(err).status(400)
})
},
the console.log(req.body) is showing the following object:
{
profile_pic: {},
f_name: 'assad',
l_name: 'jandali',
bio: 'bio',
location: 'location',
sm_facebook: 'https://facebook.com',
sm_instagram: 'https://instagram.com',
sm_twitter: 'https://twitter.com',
sm_website: 'http://omarjandali.com',
followers: 0,
following: 0,
photos: 0,
edits: 0,
downloads: 0,
userId: 4
}
as you can see the profile picture is not being sent all the way through the request.
Convert image file to base64 before sending to the backend
you can use react-file-base64 component, its pretty awsome

How to implement New FormData() for Array data from Object to do the POST method using Axios, ReactJs?

On the backend I use multer to upload multiple files / images, I have tried using Postman and it works. but when i apply it on the frontend using reactjs, i am confused
sample case:
state = {
name: 'product1',
price: '200',
images: [{name: "1.png", lastModified: 1593401931873, lastModifiedDate: Mon Jun 29 2020 10:38:51 GMT+0700 (Waktu Indochina), webkitRelativePath: "", size: 176924},
{name: "2.png", lastModified: 1593401931873, lastModifiedDate: Mon Jun 29 2020 10:38:51 GMT+0700 (Waktu Indochina), webkitRelativePath: "", size: 176924}],
files: [{name: "1.zip", lastModified: 1593401931873, lastModifiedDate: Mon Jun 29 2020 10:38:51 GMT+0700 (Waktu Indochina), webkitRelativePath: "", size: 176924},
{name: "2.zip", lastModified: 1593401931873, lastModifiedDate: Mon Jun 29 2020 10:38:51 GMT+0700 (Waktu Indochina), webkitRelativePath: "", size: 176924}],
}
handleSubmit = () => {
const { name, price, images, files} = this.state
const body = new FormData()
body.append('name', name)
body.append('price', price)
images.map((file, i) => body.append('images[i]', file[i])) // not work
files.map((file, i) => body.append('files[i]', file[i])) // not work
axios.post(`http://localhost:3000/api/v1/add`, body)
.then((res) => res.data.data)
// result {"name":"roduct1","price":"200","images":[{},{}],"files":[{},{}]}
}
You can do the POST request through axios in this way:
var bodyFormData = new FormData();
bodyFormData.set('userName', 'Fred');
bodyFormData.append('image', imageFile);
axios({
method: 'post',
url: 'myurl',
data: bodyFormData,
headers: {'Content-Type': 'multipart/form-data' }
})
.then(function (response) {
//handle success
console.log(response);
})
.catch(function (response) {
//handle error
console.log(response);
});
Also its observed many times that localhost does not work with axios. Instead you need to use IP address. If suppose your IP address is 192.23.43.45 than URL becomes http://192.23.43.45:3000/api/v1/add . So, you can try this approach

How to add imported image to formData

I need to send the imported image as a file. I try to add it into new File() but it will not recognize the type and correct size of image and i can't send i to backend
import img from '../image.png';
...
const image= new File([img], "img.png");
console.log(image) //
lastModified: 1590023609558
lastModifiedDate: Thu May 21 2020 05:13:29 GMT+0400 (Armenia Standard Time) {}
name: "img.png"
size: 41 //(my real file size is 124KB)
type: ""
webkitRelativePath: ""

How to process data read from database

I am processing data read from database on the server using the following code:
module.exports = mongoose.model('Todo', {
text : {type : String, default: ''},
created_at : Date
});
var processTodos = function ( todos ){
for (var i = todos.length - 1; i >= 0; i--) {
// Following update is not happening
todos[i].created_at = "Custom date";
};
console.dir(todos);
return todos;
};
I am not able to figure out how to update this. Is there a syntax issue that is causing this.
I am using MEAN stack for my application.
// Following update is not happening
todos[i].created_at = "Custom date";
What am i missing here.
Here is the console log for "console.dir(todos);":
{ _id: 5489dda3f23f159400475dba,
created_at: Thu Dec 11 2014 23:38:35 GMT+0530 (India Standard Time),
__v: 0,
text: 'Testing sorting at server side' }
{ _id: 5489ddacf23f159400475dbb,
created_at: Thu Dec 11 2014 23:38:44 GMT+0530 (India Standard Time),
__v: 0,
text: 'It works' }
{ _id: 5489f31a12fa54cc127f3e1d,
created_at: Fri Dec 12 2014 01:10:10 GMT+0530 (India Standard Time),
__v: 0,
text: 'time to add more data' }
If you'd like to save the changes you're making to your object, you need to persist the change using the .save() method like so:
var processTodos = function ( todos ){
for (var i = todos.length - 1; i >= 0; i--) {
// Following update is not happening
todos[i].created_at = "Custom date";
todos[i].save();
};
console.dir(todos);
return todos;
};

Categories