Search code examples
node.jsexpressmultipartform-datamulter

Parse multipart form data and then upload a file with Multer (Node module)


I'm having some troubles trying to figure out how to prevent Multer from uploading a file if an entry has already been added to the database.

In my scenario, I have a multipart form where you can add beers specifying an id. It has 2 inputs, one with a text input (id) and another one with a file input (beerImage).

What I'd like to do is, before uploading a file, check if it already exist in the database and, if not, upload the file. Currently, my code is uploading the file first and then checking if it exists, and that's a bad thing!

That's my code:

var express = require('express');
var router = express.Router();
var multer = require('multer');
var database = require('../services/database');

var upload = multer({ dest: 'uploads/' });
var cpUpload = upload.fields([{ name: 'beerImage', maxCount: 1 } ]);

router.route('/beers')
    .post(function (req, res, next) {
        // I'd like to use req.body.id in the query here, but it doesn't exist yet!
        cpUpload(req, res, function (err) {
            if (err) {
                return next(new Error('Error uploading file: ' + err.message + ' (' + err.field + ')'));
            } else {
                database.getConnection().done(function (conn) {
                    conn.query('SELECT COUNT(*) AS beersCount FROM beers WHERE id=?', req.body.id, function (err, rows, fields) {
                        if (err) {
                            conn.release();
                            return next(err);
                        }

                        if (rows[0].beersCount > 0) {
                            conn.release();
                            return next(new Error('Beer "' + req.body.id + '" already exists!'));
                        } else {
                            delete req.body.beerImage;
                            conn.query('INSERT INTO beers SET ?', req.body, function (err, rows, fields) {
                                conn.release();

                                if (err) {
                                    return next(err);
                                }

                                res.json({ message: 'Beer "' + req.body.id + '" added!' });
                            });
                        }
                    });
                });
            }
        });
    });

module.exports = router;

I can't find a way to first "parse" the multipart form data (to be able to do the query and check if it exists using req.body.id) and then decide if I want to upload the file or not. It seems that "cpUpload" does both things at the same time!

Any idea of how to get "req.body.id" first (to do the query) and then decide if I want to upload the file?


Solution

  • I realized there is a function called "fileFilter" on Multer where you can control which files are accepted. Here I've been able to do the desired query to check if the entry exists.