Search code examples
node.jsreactjsfrontendmulteruploading

I can't figure out how to upload multiple images from frontend to database


I have an API and I'm uploading images using multer. I built backend that works perfectly fine and my images are uploaded and stored in my folder when I use postman, but when I try to upload images using frontend i dont know how to send them. I'm trying to have formData and append my files and then put that in my req.body. I need to have fields with name 'photos' but when i put my data and log req.body on backend i get data: [object FormData] and photos as an empty array. Also when i log req.files i get an empty array. My photos after extracting values from them look like this [File, File]

 const handleHotelSubmit = async (e) => {
    e.preventDefault();
    const data = new FormData();
    Object.values(photos).map((photo) => data.append("photos", photo));
    setIsLoading(true);
    try {
      await axios.post(
        `/hotels`,
        { ...info, data, featured, rooms },
        {
          headers: {
            "Content-Type": "multipart/form-data",
          },
        }
      );
    } catch (err) {
      setError(err.message);
    }
    setIsLoading(false);
  };

My multer

const multerStorage = multer.memoryStorage();
const multerFilter = (req, file, cb) => {
  if (file.mimetype.startsWith("image")) {
    cb(null, true);
  } else {
    cb(new AppError("Not an image. Please upload only images", 400), false);
  }
};
exports.resizeImage = catchAsync(async (req, res, next) => {
  console.log(req.files);
  if (!req.files) return next();
  req.body.photos = [];
  await Promise.all(
    req.files.map(async (file) => {
      const filename = `hotel-${uuidv4()}-${Date.now()}.jpeg`;
      await sharp(file.buffer)
        .resize(500, 500)
        .toFormat("jpeg")
        .jpeg({ quality: 90 })
        .toFile(`public/img/hotels/${filename}`);
      req.body.photos.push(filename);
    })
  );
  next();
});
const upload = multer({
  storage: multerStorage,
  fileFilter: multerFilter,
});
exports.uploadHotelPhotos = upload.array("photos", 5);

Again code works with postman so clearly the problem is in the frontend


Solution

  • Since you specified in the headers that the request body will be multipart/form-data, then you need to put all other fields (info, featured, rooms) inside the formData data variable