Search code examples
node.jsexpresspostmanmultipartform-datamulter

Multer middlware in Node.js returns empty object in req.body and undefined in req.file


The problem is when I use multer and send a request in Postman the req.body comes as an empty object and the req.file comes as undefined. I've unchecked the content-type header in postman.

And here's the code:

//Route
const storage = multer.diskStorage({
    destination: function (req, file, cb) {
        cb(null, '../uploads/');
    },
    filename: function (req, file, cb) {
        cb(null, new Date().toISOString() + file.originalname);
    }
});

const upload = multer({
    storage,
    limits: {fileSize: 1024 * 1024 * 10}
});

router.post('/test', upload.single('profilePicture'), authController.test);

//Controller

const test = (req, res) => {
    console.log(req.body)
    console.log(req.files)
    res.json({body:req.body, files:req.files})
}

//app.js

app.use(express.json({extended: true, limit: '30mb'}));
app.use(express.urlencoded({extended: true, limit: '30mb'}))
app.use(cookieParser());

app.use('/api/auth', authRoutes);
app.use('/api/product', productRoutes);
app.use('/api/profile', profileRoutes);

Edit: turnes out, the problem is in Postman. I made a request with axios from a React app and everything works. So the question is, why doesn't it work in Postman? Is it some Bug in software or is there some settings that we're supposed to change?


Solution

  • The problem is that Nodejs is by default uses Ansynchornus Javascript. You need to use the async-await approach and try-catch-finally methods over conventional JS programming.

    So your controller would look like -

    //Route
    router.post('/test', async (req, res, next)=>
     {
        try{
             await upload.single('profilePicture')
             next()
        } catch(err){
        console.log(err)
        res.send('failed!')
        }, 
    
    authController.test);
    
    
    //Controller
    
    const test = async (req, res) => {
       try{
    
           console.log(req.body)
           console.log(req.files)
           res.json({body:req.body, files:req.files})
        } catch(err){
        console.log(err);
        }
    
    }
    

    A late addition to the answer. If you're trying to just access the uploaded image, then you should make use of the buffer.

    var storage = multer.memoryStorage()
    var upload = multer({ storage: storage })