Skip to content

Instantly share code, notes, and snippets.

@milinmestry
Created September 21, 2017 09:25
Show Gist options
  • Save milinmestry/a62a7f41976cf7d4a051b35b916af685 to your computer and use it in GitHub Desktop.
Save milinmestry/a62a7f41976cf7d4a051b35b916af685 to your computer and use it in GitHub Desktop.
Handle unique column validation in ExpressJs
I am following this tutorial to learn ExpressJS: https://developer.mozilla.org/en-US/docs/Learn/Server-side/Express_Nodejs
I need to validate genre name before update query is call to save/update the data into database.
If I'm not handling unique name validation, then mongoDB will throw E11000 duplicate key error.
There may be better approach(es) to solve this problem, but as a new learner of ExpressJS I have solve it in this way.
Using nodeJS async-parallel, I am calling the validation for checking unique genre name in the database along with
other form validations. If there is/are any problem in the web form I can show the error(s) on the browser or else
save the form data into the database.
// Filepath: models/genre.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var GenreSchema = Schema({
name: {type: String, required: true, min:3, max: 100, unique: true},
description: {type: String, max: 500},
});
// Check if genre name (case-insensitive) is already exists in the database.
GenreSchema.query.isGenreExists = function (name, id) {
if (id !== undefined) {
return this.count({ name: new RegExp(name, 'i'), _id: {$ne: id} });
}
return this.count({ name: new RegExp(name, 'i') });
};
// Virtual for Genre URL
GenreSchema
.virtual('url')
.get(function () {
return '/catalog/genre/' + this._id;
});
// export model
module.exports = mongoose.model('Genre', GenreSchema);
// Filepath: controllers/genreController.js
// Handle Genre update on POST
exports.genre_update_post = function(req, res, next) {
async.parallel({
genreFound: function(callback) {
// No name is provided, just return -1
if (req.body.name === '') {
// https://stackoverflow.com/questions/20186081/understanding-node-js-async-parallel
callback(null, -1);
} else {
// Check genre exists in the database
Genre.find().isGenreExists(req.body.name, req.params.id).exec(callback);
}
},
}, function(err, results) {
if (err) {
return next(err);
}
req.sanitize('id').escape().trim();
req.checkBody('name', 'Genre name required.').notEmpty();
req.sanitize('name').escape().trim();
var errors = req.validationErrors();
if (results.genreFound > 0) {
errors = [{msg: 'Genre already exists!'}];
}
var genre = new Genre({
_id: req.params.id,
name: req.body.name
});
if (errors) {
res.render('genre_form', {title: 'Update Genre', genre: genre, errors: errors});
return;
} else {
// Update the Genre name
Genre.findByIdAndUpdate(req.params.id, genre, {}, function(err, theGenre) {
if (err) {
return next(err);
}
res.redirect(theGenre.url);
});
}
});
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment