Search code examples
htmlnode.jsmulter

Node.js image upload


I am uploading an image using Multer. The image is uploading just fine. But the main problem is that I cant retrieve the other input text fields data from req.body. My req.body is {}.

HTML CODE

<form action="/postRoute" method="POST" enctype="multipart/form-data">
    <div class="form-group row">
        <div class="col-sm-6 mb-3 mb-sm-0">
            <input type="text" placeholder="Title" name="title">
        </div>
        <div class="col-sm-6">
            <input type="text" placeholder="Description" name="description">
        </div>
    </div>
    <div class="file-field input-field">
        <div class="btn grey">
            <span>Image</span>
            <input type="file" name="image" multiple>
        </div>
    </div>
    <button type="submit" class="btn btn-primary btn-user btn-block">
        List
    </button>
</form>

ROUTE CODE

router.post('/postRoute', (req, res) => {
    console.log(req.body);

    upload(req, res, (err) => {
        if(err) {
         throw err;   
        } else {
            console.log('logging files');
            console.log(req.files);

            if(req.files.length <= 0) {
                res.render('listing', {
                    msg: 'Error: No File Selected!'
                })
            } else {
                let list = Listing();
                list.title = title;
                list.description = description;
                list.photos = req.files[0].filename
                
                list.save((err) => {
                    if(err) throw err;
            
                    req.flash('success', 'Product Listed Successfully!')
                    res.redirect('/')
                })
            }
        }
    })
})

MULTER CODE

//Set Storage Engine
const storage = multer.diskStorage({
    destination: './public/uploads/',
    filename: function(req, file, cb) {
        cb(null, file.fieldname + '-' + Date.now() + path.extname(file.originalname));
    }
})

//Init Upload
const upload = multer({
    storage: storage,
    llmits: {fileSize: 1000000},
    fileFilter: (req, file, cb) => {
        checkFileType(file, cb);
    }
}).array('image')

//Check File Type
function checkFileType (file, cb) {
    //Allowed ext
    const fileType = /jpeg|jpg|png|gif/;

    //Check ext
    const extname = fileType.test(path.extname(file.originalname).toLowerCase());

    //Check Mime
    const mimetype = fileType.test(file.mimetype)

    if(mimetype && extname) {
        return cb(null, true);
    } else {
        cb('Error: Images Only!');
    }
}

When I remove enctype="multipart/form-data" from the form, I receive my req.body with data, but, then my image won't come.


Solution

  • You need to use multer as a middleware:

    router.post('/postRoute', upload, (req, res) => {
        console.log(req.body);
     // other code
    }
    

    See documentation