1
votes

Whenever I upload an image, req.files returns undefined. This is my code:

 var upload123 = multer({
    dest: path.join(__dirname, 'public/upload/temp'),
  });

  app.post(upload123);

This is the HTML:

<form action="/images" method="POST" enctype="multipart/form-data">
  <div class="panel-body form-horizontal">
    <div class="form-group col-md-12">
      <label for="file" class="col-md-2 control-label">Browse:</label>
      <div class="col-md-10">
        <input type="file" class="form-control" id="file" name="file">
      </div>
    </div>

This is the controller I am trying to access req.files in:

create(req, res) {
const saveImage = function() {
  const possible = 'abcdefghijklmnopqrstuvwxyz0123456789';
  let imgUrl = '';

  for(let i = 0; i < 6; i++) {
    imgUrl += possible.charAt(Math.floor(Math.random() * possible.length));
  }

  Models.Image.find({ filename: imgUrl }, (err, images) => {
    if (images.length > 0) saveImage();
    else {
      var tempPath = req.files.file.path,
      ext = path.extname(req.files.file.name).toLowerCase(),
      targetPath = path.resolve(`./public/upload/${ imgUrl }${ ext }`);

      if (ext === '.png' || ext === '.jpg' || ext === '.jpeg' || ext === '.gif') {
        fs.rename(tempPath, targetPath, (err) => {
          if (err) throw err;
          var newImg = new Models.Image({
            title: req.body.title,
            description: req.body.description,
            filename: imgUrl + ext
          });

          newImg.save((err, image) => {
            res.redirect(`/images/${image.uniqueId}`);
          });
        });
  } else {
    fs.unlink(tempPath, () => {
      if (err) throw err;
      res.json(500, {error: 'Only image files are allowed'});
    })
  }
    }
  });

}

saveImage();

}

I am using Express version 4.16.3 and Multer 1.3.0. I check the docs but couldn't figure out how to simply provide a dest option in Multer. Please help, am new to Nodejs

1
How your route looks? - rkm

1 Answers

0
votes

This is example from code that is working properly:

const multer = require('multer');
const storage = multer.memoryStorage();
const fileUpload = multer({storage});

app.use('/*', fileUpload.single('file'));

If you have this in beginning of your application and you put controllers after this middleware, then in req.file you will have file

The best thing is that it is stored directly in memory, not in some file, so you dont have to load it from filesystem. (which is also safer, especially when you deploy your app to some cloud services and containers, which makes it less visible)


If you insist on your "file-on-disk" solution, based on official docs: https://www.npmjs.com/package/multer you should use it as this:

  var upload123 = multer({
    dest: path.join(__dirname, 'public/upload/temp'),
  });

  app.post('/endpoint/to/upload/photos', upload123.single('file'), controller.handleImage);