14

How are you handling form validation with Express and Mongoose? Are you using custom methods, some plugin, or the default errors array?

While I could possibly see using the default errors array for some very simple validation, that approach seems to blow up in the scenario of having nested models.

Chance
  • 11,043
  • 8
  • 61
  • 84

3 Answers3

19

I personally use node-validator for checking if all the input fields from the user is correct before even presenting it to Mongoose.

Node-validator is also nice for creating a list of all errors that then can be presented to the user.

Nican
  • 7,825
  • 3
  • 27
  • 26
  • I hadn't seen that, thanks. I don't like how the validation is tied so closely to the routes/controller logic though. Seems like you'd end up repeating yourself a good bit. – Chance Sep 29 '11 at 17:18
  • 2
    Where would you like the validation handled? Controller/route is the right place, because that's the "entry point" of data into your system. You could offload that to the model, but the model is worried about data persistence/retrieval. The controller/route is the best place. – jcolebrand Sep 29 '11 at 17:26
  • 5
    In most domain driven design, the models are concerned with business logic, data integrity, and rule validation while other players (and even itself) are concerned with data persistence/retrieval. I realize that the models handle the data portion, but I believe they should also handle validation as well. I wouldn't really consider it "offloading" it to them. – Chance Sep 29 '11 at 17:29
  • 1
    I like this, but should one include client-side validation as well before sending it to the server? – Stephen Oct 17 '11 at 17:54
  • imho, validate in each of the client, controller, and data layers! – wprl Dec 07 '12 at 23:07
  • I know this is a very old post, but just wanted to know if express validator which is based on node-validator and is just a middle ware be good enough? – Saransh Mohapatra Jul 03 '13 at 06:39
14

Mongoose has validation middleware. You can define validation functions for schema items individually. Nested items can be validated too. Furthermore you can define asyn validations. For more information check out the mongoose page.

var mongoose = require('mongoose'),
    schema = mongoose.Schema,
    accountSchema = new schema({
      accountID: { type: Number, validate: [
        function(v){
          return (v !== null);
        }, 'accountID must be entered!'
      ]}
    }),
    personSchema = new schema({
      name: { type: String, validate: [
        function(v){
          return v.length < 20;
        }, 'name must be max 20 characters!']
      },
      age: Number,
      account: [accountSchema]
    }),
    connection = mongoose.createConnection('mongodb://127.0.0.1/test');
    personModel = connection.model('person', personSchema),
    accountModel = connection.model('account', accountSchema);

...
var person = new personModel({
  name: req.body.person.name, 
  age: req.body.person.age,
  account: new accountModel({ accountID: req.body.person.account })
});
person.save(function(err){
  if(err) {
    console.log(err);
    req.flash('error', err);
    res.render('view');
  }
...
});
Erhan
  • 1,126
  • 8
  • 11
  • Yep, but if you have like PersonSchema = new Schema({ account : AccountSchema }); where AccountSchema has validation, the errors are not bubbled up. – Chance Oct 17 '11 at 18:13
  • Stephen: I guess Backbone's model validation can be used on client side. But it can be somewhat confusing, mixed client/server side code. [Dailyjs wrote about it](http://dailyjs.com/2011/04/04/node-tutorial-19/) – Erhan Oct 17 '11 at 19:29
  • Er, sorry I meant PersonSchema = new Schema({ accounts : [AccountSchema] }), not the other way (which isn't possible - my mistake). When I had a collection, I wasn't getting the errors bubbled up. I'll try it again and see if it works. Thanks. – Chance Oct 17 '11 at 19:55
  • I missed what you did originally, this is what I ended up going with (thanks). – Chance Oct 20 '11 at 03:15
5

I personaly use express-form middleware to do validation; it also has filter capabilities. It's based on node-validator but has additional bonuses for express. It adds a property to the request object indicating if it's valid and returns an array of errors.

I would use this if you're using express.

Chaz
  • 3,232
  • 5
  • 19
  • 12