Reputation: 484
I am trying to upload a PDF file using React Hook Form with next.js in the frontend and node.js in the backend.
The frontend:
const FileUpload = () => {
const [proof, setProof] = useState({})
const onSubmit = async (values) => {
try {
const proof = values.proof[0]
let { data } = await axios.post('/api/upload-file', {
proof,
})
setProof(data)
} catch (err) {
console.log(err.response)
}
}
<form onSubmit={handleSubmit(onSubmit)} className={styles['form']}>
<label htmlFor="proof" className={styles['form-input-label']}>
<input
type="file"
name="proof"
{...register('proof')}
placeholder=" "
required
className={`${
errors.proof? styles['form-input-error'] : styles['form-input']
}
)`}
/>
<span className={styles['form-input-placeholder']}>
upload file
</span>
</label>
<p className={styles['form-error']}>{errors.file?.message}</p>
<button
type="submit"
className="btn"
disabled={!isDirty || !isValid || loading}
>
{loading ? <LoadingOutlined spin /> : 'Upload File'}
</button>
</form>
</>
)
}
export default FileUpload
The backend (/api/upload-file):
export const uploadFile = async (req, res) => {
try {
console.log(req.body) // => returns empty object (proof:({}))
const { proof } = req.body
if (!proof) return res.status(400).send('File missing')
// prepare the file
const base64Data = new Buffer.from(
proof.replace(/^data:proof\/\w+;base64,/, ''),
'base64'
)
const type = proof.split(';')[0].split('/')[1]
// image bucket params
const params = {
Bucket: 's3-bucket',
Key: `${nanoid()}.${type}`,
Body: base64Data,
ACL: 'public-read',
ContentType: 'application/pdf',
}
// upload to s3
s3.upload(params, (err, data) => {
if (err) {
console.log(err)
res.sendStatus(400)
}
res.send(data)
})
} catch (err) {
console.log(err)
return res
.status(400)
.send(
'An Error occured'
)
}
}
I am not able to pass the file to the backend, all I get is an empty object. I tried researching the axios docs, as well as the react hook form docs, to no avail.
What am I doing wrong?
Thank you for your help!!
Upvotes: 2
Views: 2530
Reputation: 1
I think firstly you should test your api, using postman or swagger, try to upload a file if it is works, and redefine your onsubmit. Here you are actually passing an empty object in the moment it is empty
const proof = values.proof[0]
let { data } = await axios.post('/api/upload-file', {
proof,
})
setProof(data)
take a look at your backend service responsible for a file uploading , you can use multer or fileinterceptors
Upvotes: 0
Reputation: 11
you have to set the content type to multi-part/formdata and create a formData object to send file content to the backend. You also have to parse that file multi-part/formdata on the backend. Look up Multer for the backend and formData object for frontend.
Upvotes: 1