Multer: How can i get mutated filename value inside destination?

Created on 18 Oct 2019  ·  5Comments  ·  Source: expressjs/multer

const fs = require('fs');
const multer = require('multer');

const createDirPathFromFileName = (fileName, symbolsCount) => fileName
  .substring(0, symbolsCount)
  .split('')
  .join('/');



const storage = multer.diskStorage({
  destination: (req, file, cb) => {
    const extraDirPath = createDirPathFromFileName(file.originalname, 3);
    // определяем в какую папку класть по типу
    const type = req.params.type || 'trash';
    const path = `./static/${type}/${extraDirPath}`;
    // создаем если папки еще нет
    if (!fs.existsSync(path)) {
      fs.mkdirSync(path, { recursive: true }, err => console.error('mkdirSync couldnot create new directories', err));
    }
    cb(null, path);
  },
  filename: (req, file, cb) => {
    cb(null, `${new Date().toISOString()}_${file.originalname}`);
  },
});

const fileFilter = (req, file, cb) => {
  if ('image/jpeg' === file.mimetype || 'image/png' === file.mimetype) {
    // console.log('req.params', req.params);
    // console.log('file', file);
    cb(null, true);
  } else {
    cb(null, false);
  }
};

const upload = multer({
  storage,
  limits: {
    fileSize: 1024 * 1024 * 5, //  5mb
  },
  fileFilter,
});

module.exports = upload;

question

Most helpful comment

@Fenricage

Am i right that destination function always executed before filename? i think i can use scope, but i need to be sure, that im right

Yes. destination function is always executed before filename function with multer.diskStorage.
The following code calls destination function first and filename function second.
https://github.com/expressjs/multer/blob/59376904cf2317b3683368c8cbe3736356ffacd2/storage/disk.js#L28-L36

All 5 comments

Am i right that destination function always executed before filename? i think i can use scope, but i need to be sure, that im right

I just need to create directory path from mutatedFilename, but i cant get it within destination

@Fenricage

Am i right that destination function always executed before filename? i think i can use scope, but i need to be sure, that im right

Yes. destination function is always executed before filename function with multer.diskStorage.
The following code calls destination function first and filename function second.
https://github.com/expressjs/multer/blob/59376904cf2317b3683368c8cbe3736356ffacd2/storage/disk.js#L28-L36

You could perhaps use a middleware to decorate the request with the value you're going to be using later in the filename handler. Instead of using Date.now() in the filename handler, you could do that before multer is handling the file and then add it onto the req object.

I suppose you could also just add something onto the req object within the destination function, then read it later in filename function. I haven't tested this, but it would be worth a try.

possible solution provided by @jonchurch (thanks!). Closing, can re-open if more evidence of issue arises.

Was this page helpful?
0 / 5 - 0 ratings