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;
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.
Most helpful comment
@Fenricage
Yes.
destination functionis always executed beforefilename functionwithmulter.diskStorage.The following code calls
destination functionfirst andfilename functionsecond.https://github.com/expressjs/multer/blob/59376904cf2317b3683368c8cbe3736356ffacd2/storage/disk.js#L28-L36