Modify req.body after file was saved by multer

Viewed 183

I can't figure out a simple thing. If I do pass files with the request, I want to save them, and then modify req.body a little bit inside the same multer middleware. My multer middleware:

const storage = multer.diskStorage({
    destination: (req, file, cb) => {
        cb(null, './uploads/')
    },
    filename: (req, file, cb) => {
        cb(null, req.body._id + path.extname(file.originalname))
    },
})

const fileFilter = (req: Request, file: Express.Multer.File, cb: multer.FileFilterCallback) => {
    if (
        file.mimetype === 'audio/wave' ||
        file.mimetype === 'image/png' ||
        file.mimetype === 'image/jpeg'
    )
        return cb(null, true)

    cb(null, false)
}
const upload = multer({
    storage: storage,
    limits: {
        fileSize: 1024 * 1024 * 3, // up to 3 megabytes
    },
    fileFilter: fileFilter,
})

export const saveFiles = upload.fields([
    { name: 'audio', maxCount: 1 },
    { name: 'image', maxCount: 1 },
])

Right now I do it in the router:

if (req.files) {
        if ((req as any).files.audio)
            req.body.data.audio = (req as any).files.audio[0].path.replace('\\', '/')
        if ((req as any).files.image)
            req.body.data.image = (req as any).files.image[0].path.replace('\\', '/')
    }

Which is kinda annoying, I would like to just do it inside the multer somehow before it fires next(). I just can't figure out how.

1 Answers

So, saveFiles is your middleware function. You don't show where you actually use it, but presumably you are registering it in your router as middleware somewhere. Because it's middleware, that means it is a function that expects to be called with the arguments (req, res, next). You can replace that next argument with your own and do your work in their like this:

// multer's middlware function, we will wrap
const saveFilesMiddleware = upload.fields([
    { name: 'audio', maxCount: 1 },
    { name: 'image', maxCount: 1 },
]);

// wrap the multer middleware with our own
export const saveFiles = function(req, res, next) {
     saveFilesMiddleware(req, res, err => {
         if (err) {
             // upon error, just call the real next with the error
             next(err);
         } else {
             // when no error, do our housekeeping in req.body
             if (req.files) {
                if ((req as any).files.audio)
                     req.body.data.audio = (req as any).files.audio[0].path.replace('\\', '/');
                if ((req as any).files.image)
                     req.body.data.image = (req as any).files.image[0].path.replace('\\', '/');
             }
             next();
         }
     });        
};
Related