Jahid Hasan
Jahid Hasan

Reputation: 13

Node js (multer) req.file and req.files always undefined in react js but working fine with templating engines

I'm trying to upload images to my server using Multer. If I use any templating engine, the req.file and req.files are working fine. But when I try to upload images with postman or jsx form in react, It returns undefined.

I'm using: Multer - 1.4.2 Express - 4.17.1 Node - 14.16.1

server.js

const express = require("express");
const mongoose = require("mongoose");
const cors = require("cors");
const path = require("path");
const app = express();
const port = 5000;
//Routes Import
const data = require("./routes/router");

//Database Connection
mongoose
  .connect("mongodb://localhost/newConnectSix", {
   useNewUrlParser: true,
   useUnifiedTopology: true,
   useCreateIndex: true,
})
.then(console.log("connected!"));

//MiddleWares
app.use(cors());
app.use(express.json());

//Route
app.use("/", data);

//Listening the port
app.listen(port, () => {
console.log(`Listening to ${port}`);
});

multer.js

const multer = require("multer");

//set storage
var storage = multer.diskStorage({
 destination: function (req, res, cb) {
 cb(null, "uploads");
 },
filename: function (req, file, cb) {
  var ext = file.originalname.substr(file.originalname.lastIndexOf("."));
  cb(null, file.fieldname + "-" + Date.now() + ext);
},
});

module.exports = store = multer({ storage: storage });

router.js

const express = require("express");
const store = require("../middleware/multer");
const router = express.Router();

router.post("/uploadmultiple", store.array("images", 12), (req, res) => {
  const files = req.files;
  console.log(req.files);
});

module.exports = router;

form.jsx

<form
  onSubmit={handleSubmit}
  action="/uploadmultiple"
  encType="multipart/form-data"
  method="POST"
>
<label htmlFor="">Upload images:</label>
  <input
   name="images"
   type="file"
   className="form-control"
   multiple
   />
/>

handleSubmit Function

const apiEndpoint = "http://localhost:5000/uploadmultiple";

const handleSubmit = async (e) => {
e.preventDefault();
await axios.post(apiEndpoint);
};

Upvotes: 1

Views: 1080

Answers (1)

Maxim Orlov
Maxim Orlov

Reputation: 2582

You're taking control of form submission with onSubmit and e.preventDefault(), but not sending the form with axios. You have two options:

  1. Either remove the onSubmit handler and let the browser do the request for you:

    render() {
      return (
        <form
          action="/uploadmultiple"
          encType="multipart/form-data"
          method="POST"
        >
        // ...
      );
    }
    
  2. Or do the request yourself by constructing a form and sending it with axios:

    const handleSubmit = async (e) => {
      e.preventDefault();
    
      const form = new FormData();
      for (const file of e.target.files) {
        form.append('images', file);
      }
    
      await axios.post(apiEndpoint, form, {
        headers: {
          'Content-Type': 'multipart/form-data',
        },
      });
    };
    

Upvotes: 1

Related Questions