Search code examples
htmlnode.jsexpressmongoosemulter

Multer: "ENOENT: no such file or directory"


I keep getting errors and couldn't figure out what's wrong. I'm trying to upload multiple files through Mongoose. I'm kinda new at multer, any help would be appreciated, thank you.

Here's my app.js

const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, __dirname + '/uploads')
  },
  filename: function (req, file, cb) {
    const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9)
    cb(null, file.fieldname + '-' + uniqueSuffix)
  }
})
const upload = multer({ storage: storage })
app.post('/movies', upload.array('postImages', 12), function (req, res) {
  const title = req.body.postTitle;
  const content = req.body.postContent;
  const files = req.files;

  const newImage = new Image({
    name: title,
    alt: title,
    image: {
      data: fs.readFileSync(
        path.join(__dirname + "/uploads/" + req.files.filename)
      ),
      contentType: "image/png",
    }
  });

  newImage.save();
  res.redirect("/movies");

The HTML (.ejs file)

<form action="/movies" enctype="multipart/form-data" method="POST">
  <label for="title">Title:</label>
  <input type="text" name="postTitle" required>
    
  <label for="postImages">Choose file(s):</label>
  <input type="file" name="postImages" accept="image/*" multiple>      
    
  <label for="content">Content:</label>
  <textarea name="postContent" rows="8" required></textarea>
    
  <input type="submit" value="Submit">
</form>

Schemas

const mongoose = require('mongoose');

const imageSchema = new mongoose.Schema({
  name: String,
  alt: String,
  image:
  {
      data: Buffer,
      contentType: String
  }
});
const Image = mongoose.model('Image', imageSchema);
module.exports = {
  Image
};

Solution

  • because you use multer's array() method, so get an array of file objects via req.files. Therefore, to perform an operation on each file, we need to iterate over the req.files array. I update your code like below:

    app.post('/movies', upload.array('postImages', 12), function (req, res) {
      const title = req.body.postTitle;
      const content = req.body.postContent;
      const files = req.files; // files is an Array object
    
      files.forEach(file => {
        const newImage = new Image({
          name: title,
          alt: title,
          image: {
            data: fs.readFileSync(
              path.join(__dirname + "/uploads/" + file.filename)
            ),
            contentType: "image/png",}
        });
    
        newImage.save((err) => {
          if (err) {
            console.log(err);
          }
        });
      });
      
      res.redirect("/movies");
    });