I have a problem with multer middleware. I created the middleware and set the static express files to the uploads folder.
Index.js File
import emailroutes from './routes/emailroutes.js'
app.use(express.json({ limit: '25mb' }));
app.use(express.urlencoded({ extended: false, limit: '25mb' }));
app.use('/uploads', express.static(path.join('uploads')));
app.use('/email', emailroutes);
Then in the routes file, using multer as middleware
import EmailController from '../controller/EmailController.js'
import { storageMultiple } from '../helpers/storage.js'
router.post('/', protect, storageMultiple, EmailController.postEmail)
Multer middle ware function is as follows.
import multer from 'multer';
import md5 from 'md5';
var filepatharray = [];
const diskStorageMultiple = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'uploads');
},
filename: (req, file, cb) => {
while (i < req.files.length) {
filepath = md5(Date.now() + i)
const mimeType = file.mimetype.split('/');
var fileType = mimeType[1];
if (fileType == 'vnd.openxmlformats-officedocument.spreadsheetml.sheet') {
fileType = 'xlsx'
} else if (fileType == 'text/plain') {
fileType = 'txt'
} else if (fileType == 'text/csv') {
fileType = 'csv'
} else if (fileType == 'vnd.ms-excel') {
fileType = 'xls'
} else if (fileType == 'vnd.openxmlformats-officedocument.wordprocessingml.document') {
fileType = 'docx'
} else if (fileType == 'msword') {
fileType = 'doc'
} else if (fileType == 'vnd.openxmlformats-officedocument.presentationml.presentation') {
fileType = 'pptx'
} else if (fileType == 'vnd.ms-powerpoint') {
fileType = 'ppt'
}
const fileName = filepath + '.' + fileType;
filepatharray.push({
path: filepath + '.' + fileType,
name: file.originalname
})
cb(null, fileName);
i++;
}
},
});
const fileFilter = (req, file, cb) => {
cb(null, true)
};
const storageMultiple = multer({
storage: diskStorageMultiple,
fileFilter: fileFilter).array(
'files'
);
export { storageMultiple , filepatharray}
When i change this to single file upload, it workds fine, Following is the code for multer for single file.
const diskStorage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, './uploads');
},
filename: (req, file, cb) => {
filepath = md5(Date.now() + req.user.id)
const mimeType = file.mimetype.split('/');
var fileType = mimeType[1];
if (fileType == 'vnd.openxmlformats-officedocument.spreadsheetml.sheet') {
fileType = 'xlsx'
} else if (fileType == 'text/plain') {
fileType = 'txt'
} else if (fileType == 'text/csv') {
fileType = 'csv'
} else if (fileType == 'vnd.ms-excel') {
fileType = 'xls'
} else if (fileType == 'vnd.openxmlformats-officedocument.wordprocessingml.document') {
fileType = 'docx'
} else if (fileType == 'msword') {
fileType = 'doc'
} else if (fileType == 'vnd.openxmlformats-officedocument.presentationml.presentation') {
fileType = 'pptx'
} else if (fileType == 'vnd.ms-powerpoint') {
fileType = 'ppt'
}
const fileName = filepath + '.' + fileType;
filepath = filepath + '.' + fileType
cb(null, fileName);
},
});
const storage = multer({ storage: diskStorage, fileFilter: fileFilter }).single(
'file'
);
When i am using multiple files, then i am sending as "files" in multer and when single file, then it is "file"
I am expecting that if someone helps to debug where is the issue on server.
req.files
is available after the processing, so there is no point of reading req.files
with while
loop in filename
function, which means you need to remove multiple storage handler completely, and use only single, and determine single and multiple file uploads per route. Try this:
const storage = multer({ storage: diskStorage, fileFilter: fileFilter })
// single
router.post('/', protect, storage.single('file'), EmailController.postEmail)
// multiple
router.post('/', protect, storage.array('files'), EmailController.postEmailWithMultipleFiles)
And if you need filepatharray
, you can extract that from req.files
The difference is that with multiple files, files are stored in req.files
, and with single in req.file
, so in your case you might not need single at all..