question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Upload with express-validator

See original GitHub issue

I have a simple blog post upload form with post_name, post_content & post_image. How & where can I start using check validator function? Please help.

Here is my add-post.ejs code

<% include partials/header %>
	<div class="body-content container">
		<div class="col-md-9 col-xs-12">
			<form method="post" enctype="multipart/form-data">
				<fieldset class="form-group row">
					<legend class="col-form-legend col-sm-1-12">Add New Post</legend>

					<% if( errors ) { %>
						<p class="text-danger">Please fix the following errors.</p>
						<ul>
							<% errors.forEach( function( error ) { %>
								<li class="text-danger">
										<%= error.msg %>
								</li>
							<% }) %>
						</ul>
					<% } %>

					<div class="col-sm-1-12">
						<div class="form-group">
							<label class="col-sm-1-12 col-form-label">Post Title</label>							
							<input type="text" class="form-control" name="post_title" placeholder="">							
						</div>
						<div class="form-group">
							<label>Post Content</label>
							<textarea type="text" name="post_content" rows="5" class="form-control" placeholder=""></textarea>
						</div>
						<div class="form-group">
							<label>Featured Image</label>
							<input type="file" name="post_image" id="post_image" accept="image/*">
						</div>
						<div class="form-group">
							<button type="submit" class="btn btn-primary">Submit Post</button>
						</div>
					</div>
				</fieldset>
			</form>
		</div>
		<% include partials/sidebar %>
	</div>

	<% include partials/footer %>

My app.js code:

var express = require('express');
var bodyParser = require('body-parser');
var path = require('path');
var multer = require('multer');
//var expressValidator = require('express-validator');
const { check, validationResult } = require('express-validator/check');
const { matchedData, sanitize } = require('express-validator/filter');
var storage = multer.diskStorage({
	destination: function (req, file, callback) {
		callback(null, 'uploads/')
	},
	filename: function (req, file, callback) {
		console.log(file)
		callback(null, file.fieldname + '-' + Date.now() + path.extname(file.originalname))
	}
})

var app = express();

// Set view engine
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views'));

// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: true }));

// Set static path
app.use(express.static(path.join(__dirname, 'public')));

// Global vars
app.use(function (req, res, next) {
	res.locals.errors = null;
	res.locals.rep = null;
	next();
});


// Homepage
app.get('/', function (req, res) {
	res.render('index', {
		title: 'Homepage'
	});
});

// Render Add New Post 
app.get('/add-post', function (req, res) {
	res.render('add-post', {
		title: 'Add New Post'
	});
});

// Post New Post
app.post('/add-post', (req, res, next) => {
	
	// Image upload
	var upload = multer({
		storage: storage,
		fileFilter: function (req, file, callback) {
			var ext = path.extname(file.originalname)
			if (ext !== '.png' && ext !== '.jpg' && ext !== '.gif' && ext !== '.jpeg') {
				return callback(res.end('Only images are allowed'), null)
			}
			callback(null, true)
		}
	}).single('post_image');

	upload(req, res, function (err) { 
		if( err ) {
			res.end(err);
		} else {
			console.log(req.body);
		}

		var re1 = check('post_title').isEmpty().withMessage('Post title is required');

		// Get the validation result whenever you want; see the Validation Result API for all options!
		const errors = validationResult(req);
		if (!errors.isEmpty()) {
			return res.render('add-post', {
				title: 'Add New Post',
				errors: errors.array(),
				rep: re1
			});				
		} else {
			return res.render('add-post', {
				title: 'Add New Post',
				rep: re1
			});				
		}

				
	});
});

// Start server
app.listen(3000, function (req, res) {
	console.log('Server started at port 3000...');
});

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:9 (3 by maintainers)

github_iconTop GitHub Comments

13reactions
LinusUcommented, Nov 1, 2018

Store the files somewhere temporarily, verify the body, and then either trash the file or move it to permanent storage…

1reaction
gbagiryancommented, Dec 28, 2020

Hi, i know this issue is old, and closed. But searching for how to validate multer fileuploads (and any file uploads actually) this is one of the first search results. In case you’re searching for an easy way to validate the files in the request, one way to do it’s using “checkSchema” to check for basically anything in the request object. You can do something like this:

const multer = require('multer');

const upload = multer({
    limits: {fileSize: 10 * Math.pow(1024, 2 /* MBs*/)},
    fileFilter(req, file, cb){
        //Validate the files as you wish, this is just an example
        cb(null, file.mimetype === 'application/pdf');
    },
});

const {check, checkSchema, validationResult} = require('express-validator');

app.post('/test', [
    upload.fields([
        {name: 'resume_file', maxCount: 1},
        {name: 'another_file', maxCount: 3},
    ]),
    check('email', 'Email field is invalid, etc etc').not().isEmpty().isEmail().isLength({max: 255}),
    checkSchema({
        'resume_file': {
            custom: {
                options: (value, { req, path }) => !!req.files[path],
                errorMessage: 'You should upload a PDF file up to 10Mb',
            },
        },
        'another_file': {
            custom: {
                options: (value, { req, path }) => !!req.files[path] && req.files[path].length >= 2,
                errorMessage: 'You should upload at least two PDF files, up to 10Mb',
            },
        },
    }),
    (req, res, next) => {
        const errors = validationResult(req);

        if(!errors.isEmpty()){
            return res.status(422).json({
                message: 'Request fields or files are invalid, but im handling all of them together!',
                errors: errors.array(),
            })
        }

        //Your route logic, knowing that both the fields, and the files are valid

        return res.status(200).json({
            message: 'Request fields and files are valid!',
        })
    }
]);

And now you can have all your errors messages handled by express-validator, while the file will only be uploaded if it is a valid file acording to your multer fileFilter. Bear in mind that if you’re using multer.only(field), etc, you will have to change the custom options in the validator accordingly, since .only will make the only file available at req.file, instead of at req.file[path].

Hey man. I was wandering if you could help me out. I tried posting on stackoverflow and searching for an answer, but got nothing. The problem is when I use express-validator and send multipart/form-data, the notEmpty() check doesn’t work. It just takes undefined fields and sets their values as ‘undefined’.

Hey! Your problem is not really coming from express-validation. Multer is just transforming the request before it gets to the validation. I think that you’re sending undefined values in the request (you shouldn’t), if you have an optional value in your frontend just send an empty string or don’t send the empty parameter and it should work.

Edit: sent while typing.

There are no words to describe how stupid I feel right now. Such a dumb mistake. Thank you very much!

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to validate file input with express-validator?
In order to validate a file input field you could use multer: middleware that adds a body object and a file ...
Read more >
how to use express-validator for validation of input file? #276
I am using express-fileupload to parse the uploaded files, and you can access the filename as req.files.myfile.name, where myfile is the ...
Read more >
Getting Started · express-validator
express -validator is a set of express.js middlewares that wraps validator.js validator and sanitizer functions. Installation. Install it using npm (make sure ...
Read more >
Form Data Validation in Node.js with express-validator
Standard Validation Rules with express-validator · isEmail() : This validator function checks if the incoming string is a valid email address.
Read more >
How to validate uploaded files in Node JS - DEV Community ‍ ‍
In this note, we'll look at how we can handle file validation and compression in Node JS. If you have a better way...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found