Well I’m developing an application that that stores multiple files to a database at once using multer middleware. I have everything set up and working but once every few tries, my upload fails with no error message. It does upload the file but does not save to the database nor generate an error message.
Below is the code for the frontend (Form and accompanying functions)
import React, { useState } from 'react'
import BackButton from '../components/BackButton';
import Spinner from '../components/Spinner';
import axios from 'axios';
import { useNavigate } from 'react-router-dom';
export const CreatePhoto = () => {
const [category, setCategory] = useState({});
const newFiles = [];
const [files, setFiles] = useState({});
const [loading, setLoading] = useState(false);
const navigate = useNavigate();
const handleChange = (e) => {
setCategory(e.target.value);
console.log(e.target.value);
}
const handlePhoto = (e) => {
setFiles(e.target.files)
}
const handleSubmit = () => {
console.log(files);
const formData = new FormData();
formData.append('category', category);
for (let i=0; i<files.length;i++){
formData.append('photo', files[i]);
}
console.log(...formData);
alert('Working for now, lets see how it goes!');
setLoading(true);
axios
.post('http://localhost:5555/uploadImage', formData)
.then(() => {
alert("Checking ...");
setLoading(false);
navigate('/');
})
.catch((error) => {
setLoading(false);
alert('An error occured. Please check console!!');
console.log(error);
});
};
return (
<div className='p-4'>
<BackButton />
<h1 className='text-3xl my-4'>Upload Photos</h1>
{loading ? <Spinner /> : ''}
<div className='flex flex-col border-2 border-sky-400 rounded-xl w-[600px] p-4 mx-auto'>
<form onSubmit={handleSubmit} encType='multipart/form-data'>
<div className='my-4'>
<label className='mb-2 inline-block text-neutral-500 dark:text-gray-800' htmlFor='category'>Category</label>
<select id="category" name="category"
className='bg-gray-50 border-2 border-yellow-600 text-gray-900 text-base rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-100 dark:border-yellow-500 dark:placeholder-gray-400 dark:text-gray-800 dark:focus:ring-blue-500 dark:focus:border-blue-500'
onChange={handleChange}>
<option defaultValue={'Reception'}>Choose a Category</option>
<option value="Traditional">Traditional</option>
<option value="Court">Court</option>
<option value="Reception">Reception</option>
</select>
</div>
<div className='mb-3'>
<label
htmlFor="formFileMultiple"
className='mb-2 inline-block text-neutral-500 dark:text-gray-800'
>Upload Images</label>
<input
className='relative m-0 block w-full min-w-0 flex-auto cursor-pointer rounded border border-2 border-yellow-500 bg-gray-100 bg-clip-padding px-3 py-[0.32rem] text-base font-normal text-surface transition duration-300 ease-in-out file:-mx-3 file:-my-[0.32rem] file:me-3 file:cursor-pointer file:overflow-hidden file:rounded-none file:border-0 file:border-e file:border-solid file:border-inherit file:bg-transparent file:px-3 file:py-[0.32rem] file:text-surface focus:border-primary focus:text-gray-700 focus:shadow-inset focus:outline-none dark:border-yellow dark:text-black file:dark:text-black'
type="file"
name="photo"
onChange={handlePhoto}
id="formFileMultiple"
multiple="multiple" />
</div>
<button className='p-2 bg-sky-300 m-8' type='submit'>
Upload
</button>
</form>
</div>
</div>
)
}
export default CreatePhoto
Here is the backend code
.
.
.
const fileStorage = multer.diskStorage({
destination: 'images',
filename : (request, file, cb) => {
cb(null, file.fieldname + '_' + Date.now() + path.extname(file.originalname));
}
});
const uploadImage = multer({
storage : fileStorage,
limits : {
fileSize: 10000000
},
fileFilter(request, file, cb) {
if (!file.originalname.match(/.(png|jpg|jpeg)$/)) {
return cb(new Error('Please upload an Image file!'));
}
cb(undefined, true);
}
});
app.post('/uploadImage', uploadImage.array('photo', 20), async (request, response) => {
const files = request.files;
console.log(request.body);
console.log(request.files);
const imgArray = await files.map((file) => {
const img = fs.readFileSync(file.path);
return img.toString('base64');
});
imgArray.map(async (src, index) => {
const finalImg = {
title : files[index].originalname,
path : files[index].path,
fileSize : files[index].size,
category : request.body.category
}
console.log();
const newUpload = new Photo(finalImg);
try {
await newUpload.save();
console.log("Upload was good");
response.json('Upload was successful!!');
} catch (error) {
response.status(400).json({error:error.message || `Something went wrong somewhere`});
}
});
});
Well I tried making the post request asynchronous since my idea was that I was experiencing lags due to database connection problems; maybe slow connectivity or something like that. So I thought using async will solve the problem but I’m not very sure if I used it effectively or if it just wouldn’t help in this case.
So effectively what I’m expecting is to have a function where all upload commands succeed or where if there’s a reason why the upload isn’t working, I have a particular error message generated.
Teke Bethelson is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.