Search code examples
reactjsform-data

FormData Append Doesn't Add Files to Send to Backend


Morning,

I want to understand why my formData isn't appending the files. I am currently checking the formData with console.log(formData.entries() and it is coming back empty. This is the same when trying to process it on the backend.

Below is the code that I am using and the console information I am receiving. The file information is in the variables, I just don't understand why it's not appending.

---Update - I am able to see the formData with the for loop...

The req.body shows {} and req.files is undefined... Server Code Posted Below..

Frontend

 async function handleMultipleSubmit(event) {
      const formData = new FormData();

      console.log(files);

      files.forEach((file, index) => {
        console.log(file);
        formData.append(`file${index}`, file);
      });

      for (const [ key, value] of formData.entries()) {
        console.log(key, value);
      }

      await axios
        .post("/api/farmers/csv", formData)
        .then((response) => {
          if (response.data.success) {
            console.log(response.data.results);
          } else {
            console.log(response);
          }
        })
        .catch((error) => {
          console.log(error);
        });
    }

    if (files.length > 0) {
      handleMultipleSubmit();
    }
  }, [files]);

Image of the FormData posting to Server

Console Log

Server Code

const multer = require("multer");
const fs = require("fs");
const path = require("path");

// Configure multer storage and file name
const storage = multer.diskStorage({
  destination: (req, file, cb) => {
    cb(null, "uploads/");
  },
  filename: (req, file, cb) => {
    cb(null, Date.now() + "-" + file.originalname);
  },
});

// Create multer upload instance
const upload = multer({ storage: storage });

// Custom file upload middleware
exports.uploadMiddleware = (req, res, next) => {
  console.log(req);
  console.log(req.body);
  console.log(req.files);
  // Use multer upload instance
  upload.array("files", 5)(req, res, (err) => {
    if (err) {
      return res.status(400).json({ error: err.message });
    }

    // Retrieve uploaded files
    const files = req.files;
    const errors = [];

    console.log(files);

    // Validate file types and sizes
    files.forEach((file) => {
      const allowedTypes = ["text/csv"];
      const maxSize = 5 * 1024 * 1024; // 5MB

      if (!allowedTypes.includes(file.mimetype)) {
        errors.push(`Invalid file type: ${file.originalname}`);
      }

      if (file.size > maxSize) {
        errors.push(`File too large: ${file.originalname}`);
      }
    });

    // Handle validation errors
    if (errors.length > 0) {
      // Remove uploaded files
      files.forEach((file) => {
        fs.unlinkSync(file.path);
      });

      return res.status(400).json({ errors });
    }

    // Attach files to the request object
    req.files = files;

    // Proceed to the next middleware or route handler
    next();
  });
};


Solution

  • You cannot directly do

    console.log(formData.entries());
    

    Instead try this -

    console.log(Object.fromEntries(formData.entries()));
    

    Try this so that you can actually know that formData is appending or not. Also please share the backend code.