Created
September 21, 2017 09:25
-
-
Save milinmestry/a62a7f41976cf7d4a051b35b916af685 to your computer and use it in GitHub Desktop.
Handle unique column validation in ExpressJs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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