Search code examples
javascriptmulter

How to verify the mimetype of multiple files from a multer.array function?


I've been working on this for hours and still can't come up with a solution! My original code is to check the mimetype of a single image uploaded with multer and it works well, but I'm having trouble applying this code to multiple images. I'm not sure if I'm even approaching this the right way and may need to come up with a new approach. Please see the code below:

Multer Middleware

const multerOptions = {
    storage: multer.memoryStorage(),
    fileFilter(req, file, next) {
        const isPhoto = file.mimetype.startsWith('image/');
        if(isPhoto) {
            next(null, true);
        } else {
            next({ message: 'That filetype isn\'t allowed!'}, false);
        }
    }
};

Original Multer Function for Single Image

exports.upload = multer(multerOptions).single('photo');

exports.resize = async (req, res, next) => {
    // check if there is no new file to resize
    if (!req.file) {
        next(); // skip to the next middleware
        return;
    } 
    const extension = req.file.mimetype.split('/')[1];
    req.body.photo = `${uuid.v4()}.${extension}`;
    // resize the image
    const photo = await jimp.read(req.file.buffer);
    await photo.resize(800, jimp.AUTO);
    await photo.write(`./public/uploads/${req.body.photo}`);
    next();
};

New Multer Function for Multiple Images

exports.upload = multer(multerOptions).array('photo',[5]);

exports.resize = async (req, res, next) => {
    // check if there is no new file to resize
    if (!req.files) {
        next(); // skip to the next middleware
        return;
    } 
    imageArray = req.files;
    const extensions = [];
    for (var i = 0; i < imageArray.length; i++) {
        imageArray[i].mimetype.split('/')[1].push(extensions);
    }
    // I HAVEN'T MADE IT PAST THIS LINE YET AND AM STILL STUCK ABOVE
    req.body.photo = `${uuid.v4()}.${extension}`;
    // resize the image
    const photo = await jimp.read(req.files.buffer);
    await photo.resize(800, jimp.AUTO);
    await photo.write(`./public/uploads/${req.body.photo}`);
    next();
};

Solution

  • It's hard to know exactly what is wrong, but by using async await, can't you simply wrap your single working example in a for loop? For example:

    imageArray = req.files;
    for (var i = 0; i < imageArray.length; i++) {
      const file = imageArray[i]
      const extension = file.mimetype.split('/')[1]
      const name = `${uuid.v4()}.${extension}`
      // resize the image
      const photo = await jimp.read(file.buffer)
      await photo.resize(800, jimp.AUTO)
      await photo.write(`./public/uploads/${name}`)
    }
    next()
    

    This is literally exactly what you have in your working single example, but wrapped in a loop.