Mongoose – How to save a boolean value from a checkbox using mongoose and express

expressmongoose

I can't figure an easy way to save a boolean value with express and mongoose. I have this schema:

var ClientSchema = new Schema({
  name: {type: String, required: true, trim: true},
  active: {type: Boolean }
});

var Client = mongoose.mode('Client', ClientSchema);

This is my controllers

exports.new = function(req, res) {
  var client = new Client();
  res.render('clients/new', { item: client } );  
};

exports.create = function(req, res) {
  var client = new Client(req.body);

  client.save(function(err, doc) {
    if (err) {
      res.render('clients/new', { item: client });
    }
    ....
  });
};

And this is my view

form(method='post', action='/clients', enctype='application/x-www-form-urlencoded')
  input(type='text', name='name', value=item.name)
  input(type='checkbox', name='active', value=item.active) 

Mongoose has the ability to map the params on req.body. On the line var client = new Client(req.body), client has the property name created from req.body with the correct value passed from the form, but the property active doesn't reflect the checkbox state.

I know that I can solve this problem adding this line after var client = new Client(req.body), but I must do it for every checkbox I add to my forms:

client.active = req.body.active == undefined ? false : true;

Question edited

I don't need to do that trick on ruby on rails. How can I use checkboxes without adding the previous line for every checkbox? This is the only way to save values from checkboxes or is there any alternative?

Edit

I have another case where the schema is defined this way

var ClientSchema = new Schema({
  name: {type: String, required: true, trim: true},
  active: {type: Boolean, default: true }
});

Note that active is true by default, so if I uncheck the checkbox, active it will be true, not false.

Best Answer

Ruby on rails will output a hidden field alongside a checkbox field:

<input name="model_name[field_name]" type="hidden" value="false">
<input id="model_name_field_name" name="model_name[field_name]" type="checkbox" value="true">

This is to get around the fact that checkboxes that are not checked do not sent post data. See Does <input type="checkbox" /> only post data if it's checked? for more about that.

The trick here, by RoR, is the hidden field and the checkbox have the same value for the name attribute. If the checkbox is checked, the value of the checkbox field will be sent as post data, else the value of the hidden field will be sent.

This was certainly the case in RoR version 3.x

More information about this 'gotcha' can be found here: http://apidock.com/rails/ActionView/Helpers/FormHelper/check_box

You will either need to implement this sort of thing in your node application or check for undefined as you have been.

Related Topic