Reputation: 1573
I would like to be able to define classes for mongoose instead of using the normal Schema and then defining functions for that. I have a class like such:
var odd = function() {
this.name = String;
this.someprop = {
type: String,
required: true
}
}
this class then has some functions:
odd.prototype.cake = function() {
return "This cake has the name \"" + this.name + "\".";
}
Normally in mongoose I have to define the last function after I have created my schema, but I loose my intellisense by doing that (More than it already is).
Is there a good way to make my class into a mongoose schema without too much hassle?
Upvotes: 2
Views: 2130
Reputation: 1573
The best way I have been able to find is to create a helper function like this, which I have then put into a seperate file:
var mongoose = require("mongoose");
var Schema = mongoose.Schema;
var helpers = require("./helpers");
/**
* Dark wizardry function that creates a mongoose schema from a normal JS class
* Objects can also be passed along, and any properties that has methods will be turned into methods on the mongoose Schema.
* @param c The class to creare the schema from
* @param options The additional options to pass to the schema creation
* @returns {Schema} A new mongoose schema for the describing the given class
*/
module.exports = function(c, options) {
var f = null;
// Figure out if f is an object or a function, and take appropriate action
if(helpers.isFunction(c)) {
f = new c();
} else if(typeof f === "object") {
f = c;
} else {
throw new TypeError("Class schema cannot work with that type. Whatever it was you supplied, probably a simple type. ");
}
var prop;
var o = {};
// Save all the properties of f into a new object
for(prop in f) {
var p = f[prop];
switch (p) {
case String:
case Number:
case Date:
case Buffer:
case Boolean:
case mongoose.Types.Mixed:
case mongoose.Types.ObjectId:
case Array:
o[prop] = p;
break;
default:
if(!helpers.isFunction(p)) {
o[prop] = p;
}
}
}
// Create the schema
var sch = new Schema(o, options);
// Create the methods for the schema
for(prop in f) {
if (prop in f) {
var func = f[prop];
switch (func) {
case String:
case Number:
case Date:
case Buffer:
case Boolean:
case mongoose.Types.Mixed:
case mongoose.Types.ObjectId:
case Array:
continue
}
if (helpers.isFunction(func)) {
sch.methods[prop] = func;
}
}
}
return sch;
};
My helpers.js contains a very simple function for isFunction
:
function isFunction(f) {
return typeof f === "function";
}
exports.isFunction = isFunction;
Then whenever I want a mongoose schema I just do the following:
var mongoose = require("mongoose");
var classSchema = require("./class-schema");
var odd = function() {
...
}
odd.prototype.cake = function() {
...
}
var oddSchema = classSchema(odd, {timestamps: true});
module.exports = mongoose.model("Odd", oddSchema);
That will create a model with the same properties and the same functions as the original odd
class.
Upvotes: 1