Uploading Files using Multer in a Node.js Application

Uploading Files using Multer in a Node.js Application

·

2 min read

Multer accepts an options object, the most basic of which is the dest property, which tells Multer where to upload the files. In case you omit the options object, the files will be kept in memory and never written to disk.

By default, Multer will rename the files so as to avoid naming conflicts. The renaming function can be customized according to your needs.

The following are the options that can be passed to Multer.

KeyDescription
dest or storageWhere to store the files
fileFilterFunction to control which files are accepted
limitsLimits of the uploaded data
preservePathKeep the full path of files instead of just the base name

In an average web app, only dest might be required, and configured as shown in the following example.

const upload = multer({ dest: 'uploads/' })

If you want more control over your uploads, you'll want to use the storage option instead of dest. Multer ships with storage engines DiskStorage and MemoryStorage

const storage = multer.diskStorage({
  destination: function (req, file, callback) {
    callback(null, './uploads');
  },
  filename: function (req, file, callback) {
    callback(
      null,
      file.fieldname + '-' + Date.now() + path.extname(file.originalname)
    );
  },
});

const fileFilter = (req, file, cb) => {
  //Image only
  if (file.mimetype.split('/')[0] === 'image') cb(null, true);
  else cb(null, false);
};
const upload = multer({
  storage,
  fileFilter,
  limits: { fileSize: 10000000 }, // 10MB
});
const express = require('express');
const multer = require('multer');
const app = express();
const path = require('path');

app.get('/', (req, res) => {
  res.send(`
    <form action="/api/upload" enctype="multipart/form-data" method="post">
      <div>Text field title: <input type="text" name="title" /></div>
      <div>File: <input type="file" name="myFiles" multiple="multiple" /></div>
      <input type="submit" value="Upload" />
    </form>
  `);
});

const storage = multer.diskStorage({
  destination: function (req, file, callback) {
    callback(null, './uploads');
  },
  filename: function (req, file, callback) {
    callback(
      null,
      file.fieldname + '-' + Date.now() + path.extname(file.originalname)
    );
  },
});

const fileFilter = (req, file, cb) => {
  if (file.mimetype.split('/')[0] === 'image') cb(null, true);
  else cb(new multer.MulterError('File is not of the correct type'), false);
};
const upload = multer({
  storage,
  fileFilter,
  limits: { fileSize: 10000000 }, // 10MB
});

app.post('/api/upload', upload.any(), function (req, res, next) {
// Upload to cloudinary or aws s3
  return res.json({ success: true, data: req.files });
});

const errHandler = (error, req, res, next) => {
  const statusCode = res.statusCode === 200 ? 500 : res.statusCode;
  return res.status(statusCode).json({
    success: false,
    message: error.code,
  });
};

app.use(errHandler);

app.listen(3000, () => {
  console.log('Server listening on http://localhost:3000');
});