I cannot pass the files to my API using multer

31 Views Asked by At

I'm trying to implement a system for uploading photos for a car listing project that I'm building. I'll be honest, this is the first time using multer and I can't find what is wrong with it. I've been doing some research and looked over tutorials and also the documentation before asking here. In my POST request everything is working as planed, but the photoArray part. I've also tried converting the files into a URL using URL.createObject, but it didn't work. On both ocasions, with or without the use of URL, the req.files is empty. Thank you for any clarifications. Here is my code: 1)The front part of my aplication

 const submitData = async () => {
    const token = Cookies.get("User");

    if (token) {
      const formData = new FormData();

      // Append form data fields
      formData.append("brand", currentBrand.brand);
      formData.append("model", currentModel);
      //...deleted some appended values for ease of reading
      
      //...i'm trying to pass these photos to multer 
      photoArray.forEach((file) => {
        formData.append(`photos`, file);
      });

      await axios
        .post(
          `http://localhost:3000/api/car/create/${
            jwtDecode(token).findUser._id
          }`,
          formData,
          {
            headers: { "Content-Type": "multipart/form-data" },
          }
        )
        .then((res) => {
          setSubmit(true);
          setTimeout(() => {
            setSubmit(false);
          }, 2000);
        })
        .catch((err) => {
          setError({ state: true, message: err.response.data.message });
          setTimeout(() => {
            setError({ error: false, message: "" });
          }, 2000);
        });
    } else {
      setError({ state: true, message: "Must login first" });
      setTimeout(() => {
        setError({ state: false, message: "" });
      }, 2000);
    }
  };

2)Here is my 'Car.js' routers

const router = Router();

const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, "back/uploads");
  },
  filename: function (req, file, cb) {
    const uniqueSuffix = Date.now() + file.originalname;
    cb(null, file.fieldname + "-" + uniqueSuffix);
  },
});

const upload = multer({ storage: storage });

router.post("/create/:id", upload.any("photos"), createCar);

3)If needed, here is my controller

export const createCar = async (req, res) => {
  try {
    console.log("Files");
    console.log(req.files); // Log uploaded files
    const newCar = new Car(req.body);
    const savedCar = await newCar.save();
    const currentUser = await User.findById(req.params.id);
    if (currentUser) {
      currentUser.data.push(savedCar.id);
      await currentUser.save();
    } else {
      req.status(404).json("User error");
    }
    res.status(200).json(savedCar);
  } catch (error) {
    res.status(400).json(error);
  }
};
2

There are 2 best solutions below

0
Dat Huynh On
upload.any("photos")

You are using key "photos" instead of "files", so in your controller, if you want to access the file array, you must use syntax:

req.photos

Hpoe it's helfull.

0
sumanth On
const storage = multer.diskStorage({
  destination: "back/uploads",
  filename: function (req, file, cb) {
    const uniqueSuffix = Date.now() + file.originalname;
    cb(null, file.fieldname + "-" + uniqueSuffix);
  },
});

instead of functional declaration of the destination, can you directly declare the destination as mentioned above.