Gary
Gary

Reputation: 513

Custom constructor function in Mongoose schema/models

Greeting all!

I defined a Mongoose schema as below and registered a model (InventoryItemModel). Is there a way to create a custom constructor function for the schema, so that when I instantiate an object from the model, the function will be called (for example, to load the object with value from database)?

var mongoose = require('mongoose')
  , Schema = mongoose.Schema

var InventoryItemSchema = new Schema({
    Sku : String
  , Quanity : Number
  , Description : String
  , Carted : []
  , CreatedDate  : {type : Date, default : Date.now}
  , ModifiedDate  : {type : Date, default : Date.now}
});

mongoose.model('InventoryItem', InventoryItemSchema);

var item = new InventoryItem();

Can I add some custom constructor function so that the item will be populated from database upon instantiation?

Upvotes: 14

Views: 22525

Answers (5)

MarkMYoung
MarkMYoung

Reputation: 141

@hunterloftis provided me the answer I needed. Now, nearly 6+ years later, here is my solution for anyone else.

InventoryItemSchema.static( 'new', function( that )
{
    let instance = new InventoryItemSchema();
    Object.assign( instance, that );
    return instance;
});

or as the one-liner (which is less conducive to debugging)

InventoryItemSchema.static( 'new', function( that )
{return Object.assign( new InventoryItemSchema(), that );});

Either way, where you would like to have

let inventoryItem = new InventoryItemSchema({...});

you will instead have

let inventoryItem = InventoryItemSchema.new({...});

Upvotes: 0

ashish ranjan
ashish ranjan

Reputation: 1

You need to export. Here is an example:

import mongoose from "mongoose";

let  Schema = mongoose.Schema;


let restaurentSchema = new Schema({
  name : String
})

//export

module.exports = mongoose.model("Restaurent", restaurentSchema)

Upvotes: -5

Jorge Rivera
Jorge Rivera

Reputation: 775

Here's an implementation of option #2 from @hunterloftis's answer.

2) Write a static creation function for your schema.

someSchema.statics.addItem = function addItem(item, callback){
//Do stuff (parse item)
 (new this(parsedItem)).save(callback);
}

When you want to create a new model from someSchema, instead of

var item = new ItemModel(itemObj);
item.save(function (err, model) { /* etc */ });

do this

ItemModel.addItem(itemObj, function (err, model) { /* etc */ });

Upvotes: 6

Christopher Tarquini
Christopher Tarquini

Reputation: 11332

I ran into this problem myself and wrote a mongoose plugin that'll help solve your problem

var mongoose = require('mongoose')
  , Schema = mongoose.Schema
  , construct = require('mongoose-construct')

var user = new Schema({})
user.plugin(construct)

user.pre('construct', function(next){
    console.log('Constructor called...')
    next()
})

var User = mongoose.model('User', user)
var myUser = new User(); // construct hook will be called

Here's the repo (it's also available on npm): https://github.com/IlskenLabs/mongoose-construct

Upvotes: 2

hunterloftis
hunterloftis

Reputation: 13799

Depending on the direction you want to take, you could:

1) Use Hooks

Hooks are automatically triggered when models init, validate, save, and remove. This is the 'inside-out' solution. You can check out the docs here:

2) Write a static creation function for your schema.

Statics live on your model object and can be used to replace functionality like creating a new model. If you have extra logic for your create step, you can write it yourself in a static function. This is the 'outside-in' solution:

Upvotes: 15

Related Questions