SchemaType.prototype.set()

Parameters
  • fn «Function»
Returns:
  • «SchemaType» this

Adds a setter to this schematype.

Example:

  1. function capitalize (val) {
  2. if (typeof val !== 'string') val = '';
  3. return val.charAt(0).toUpperCase() + val.substring(1);
  4. }
  5. // defining within the schema
  6. const s = new Schema({ name: { type: String, set: capitalize }});
  7. // or with the SchemaType
  8. const s = new Schema({ name: String })
  9. s.path('name').set(capitalize);

Setters allow you to transform the data before it gets to the raw mongodb document or query.

Suppose you are implementing user registration for a website. Users provide an email and password, which gets saved to mongodb. The email is a string that you will want to normalize to lower case, in order to avoid one email having more than one account — e.g., otherwise, avenue@q.com can be registered for 2 accounts via avenue@q.com and AvEnUe@Q.CoM.

You can set up email lower case normalization easily via a Mongoose setter.

  1. function toLower(v) {
  2. return v.toLowerCase();
  3. }
  4. const UserSchema = new Schema({
  5. email: { type: String, set: toLower }
  6. });
  7. const User = db.model('User', UserSchema);
  8. const user = new User({email: 'AVENUE@Q.COM'});
  9. console.log(user.email); // 'avenue@q.com'
  10. // or
  11. const user = new User();
  12. user.email = 'Avenue@Q.com';
  13. console.log(user.email); // 'avenue@q.com'
  14. User.updateOne({ _id: _id }, { $set: { email: 'AVENUE@Q.COM' } }); // update to 'avenue@q.com'

As you can see above, setters allow you to transform the data before it stored in MongoDB, or before executing a query.

NOTE: we could have also just used the built-in lowercase: true SchemaType option instead of defining our own function.

  1. new Schema({ email: { type: String, lowercase: true }})

Setters are also passed a second argument, the schematype on which the setter was defined. This allows for tailored behavior based on options passed in the schema.

  1. function inspector (val, schematype) {
  2. if (schematype.options.required) {
  3. return schematype.path + ' is required';
  4. } else {
  5. return val;
  6. }
  7. }
  8. const VirusSchema = new Schema({
  9. name: { type: String, required: true, set: inspector },
  10. taxonomy: { type: String, set: inspector }
  11. })
  12. const Virus = db.model('Virus', VirusSchema);
  13. const v = new Virus({ name: 'Parvoviridae', taxonomy: 'Parvovirinae' });
  14. console.log(v.name); // name is required
  15. console.log(v.taxonomy); // Parvovirinae

You can also use setters to modify other properties on the document. If you’re setting a property name on a document, the setter will run with this as the document. Be careful, in mongoose 5 setters will also run when querying by name with this as the query.

  1. const nameSchema = new Schema({ name: String, keywords: [String] });
  2. nameSchema.path('name').set(function(v) {
  3. // Need to check if `this` is a document, because in mongoose 5
  4. // setters will also run on queries, in which case `this` will be a
  5. // mongoose query object.
  6. if (this instanceof Document && v != null) {
  7. this.keywords = v.split(' ');
  8. }
  9. return v;
  10. });