Reputation: 3
Problem - I have used the 'react-bootstrap' library to create a react component which handles displaying and uploading an image. At the point where I submit - the
I have a function called handleChange. Before I attempt to set the formData with useState I log the file data like so:
File {name: 'me.png', lastModified: 1686403734161, lastModifiedDate: Sat Jun 10 2023 09:28:54 GMT-0400 (Eastern Daylight Time), webkitRelativePath: '', size: 4326448, …}
lastModified: 1686403734161
lastModifiedDate: Sat Jun 10 2023 09:28:54 GMT-0400 (Eastern Daylight Time)
[[Prototype]]: Object
name: "me.png"
size: 4326448
type: "image/png"
webkitRelativePath: ""
[[Prototype]]: File
After this data is logged to the console I then instantiate a FormData object then append the file to it like so:
let data = new FormData() data.append('file', e.target.files[0]) setFormData(data)
After I set the form data I then have an async function where I call the async function called uploadFile. This is the function generated from RTK Query. Before I call this I log formData to the console and it is empty like so:
FormData {}
Here is my component code in full:
import React, { useEffect, useState } from 'react'
import { useNavigate } from 'react-router-dom'
import { Col, Container, Form, Image, Row } from 'react-bootstrap'
import NextButton from 'src/features/Buttons/NextButton'
import { useUploadFileMutation } from 'src/appState/fileApi'
import { PROFILE_LINKS } from 'src/app/App.constants'
export default function Pics() {
const navigate = useNavigate()
const [file, setFile] = useState<File>()
const [formData, setFormData] = useState<FormData>()
const [imageURL, setImageURL] = useState<string>()
const [
uploadFile,
{
data: uploadFileData,
isSuccess: isUploadFileSuccess,
isError: isUploadFileError,
error: uploadFileError,
},
] = useUploadFileMutation()
function handleChange(e: any) {
if (e.target.files[0]) {
console.log('e.target.files[0]', e.target.files[0])
let data = new FormData()
data.append('file', e.target.files[0])
setFormData(data)
setFile(e.target.files[0])
}
}
async function handleFinish() {
if (formData) {
console.log('handleFinish', formData)
await uploadFile(formData)
}
}
useEffect(() => {
if (!file) return
const newImageURL = URL.createObjectURL(file)
setImageURL(newImageURL)
}, [file])
useEffect(() => {
if (isUploadFileSuccess) {
navigate(PROFILE_LINKS.INDEX.to)
}
})
return (
<div className="pics mb-3" data-testid="pics">
<Container fluid>
<Row>
<Col>
{imageURL && (
<Image
alt="myProfilePic"
className="mb-4 shadow-sm border-primary"
src={imageURL}
width="200"
rounded
fluid
/>
)}
</Col>
</Row>
<Form className="mb-3" encType="multipart/form-data">
<Row className="mb-5">
<Col>
<Form.Group controlId="pics">
<Form.Control
accept="image/png, image/gif, image/jpeg"
size="lg"
type="file"
onChange={handleChange}
/>
</Form.Group>
</Col>
</Row>
<Row>
<Col>
<NextButton
handleNext={handleFinish}
text="Finish"
/>
</Col>
</Row>
</Form>
</Container>
</div>
)
}
I tried to search for a solution on google and in stack overflow
Upvotes: 0
Views: 377
Reputation: 3
I found a solution of how to properly log the formData object to the console...I just don't understand why but here it is
console.log(Object.fromEntries(formData))
I found the answer in this Stackoverflow post
Now I just need to figure out how to send the formData from RTK Query to my nodejs / express backend API...any help would be nice since I have not worked with formData before.
My backend API has the following controller:
export const upload = async (req, res) => {
console.log(0, req)
try {
const data = await parse(req)
console.log('data', data)
if (data) {
res.status(200).json({ message: 'Upload success', data })
} else {
res.status(404).json({ message: "Session expired. Log back in." });
}
} catch (error) {
res.status(500).json({ message: "Something went wrong", error });
console.log(error);
}
};
My controller has a utility function parse()
that parses the file using a Formidable and some AWS S3 plugins.
Upvotes: 0