Vadorequest
Vadorequest

Reputation: 17997

How to extend a class with static methods?

I want to extend my UserModel.model object with static functions. How can I do it?

As you can see below, my UserModel.model is a mongoose model object, but I need to add methods to this object, the point is: I don't know how to write it. I can't use a static{} area like in Java/C# to execute static code, I don't find the way to write it. Do you?

For instance, I want to add methods such as exists, connect, etc.

///<reference path='../../lib/def/defLoader.d.ts'/>

import model = require('./Model');

export module Models {
    export class UserModel extends model.Models.Model implements model.Models.IModel{
        /**
         * Name of the model.
         * MUST start by uppercase letter!
         */
        private static modelName: string = 'User';

        /**
         * Public readable schema as object.
         */
        public static schema: any = {
            /**
             * User Login
             */
            login: {
                type: 'string',
                minLength: 4,
                maxLength: 16,
                required: true,
                notEmpty: true,
                unique: true
            }
        };

        /**
         * Private schema as mongoose.Schema type.
         */
        private static _schema: mongoose.Schema = new mongoose.Schema(UserModel.schema);

        /**
         * The mongoose model that uses the mongoose schema.
         */
        public static model: mongoose.Model<any> = mongoose.model(UserModel.modelName, UserModel._schema);



        /**
         *************************************************************************************************
         *********************************** Public (Helpers) ********************************************
         *************************************************************************************************
         */

        /**
         * Name of the model.
         * MUST start by uppercase letter!
         */
        public modelName: string;

        /**
         * Contains the static value of the public schema as object.
         * It's a helper to always get the schema, from instance or static.
         */
        public schema: mongoose.Schema;

        /**
         * Contains the static value of the object used to manipulate an instance of the model.
         * It's a helper to always get the model, from instance or static.
         */
        public model: mongoose.Model<any>;

        /**
         * Use static values as instance values.
         */
        constructor(){
            super();

            // Use static values as instance values.
            this.modelName = UserModel.modelName;
            this.schema = UserModel.schema;
            this.model = UserModel.model;
        }

        /**
         *************************************************************************************************
         *********************************** Extended methods ********************************************
         *************************************************************************************************
         */
    }
}

Upvotes: 1

Views: 2679

Answers (1)

WiredPrairie
WiredPrairie

Reputation: 59763

I'd suggest you just use the standard MongooseJS way of adding a static method to a Model by using the statics property of a Schema instance as shown below.

module MongooseDemo {
    export class Demo {
        public static LoginSchema: any = {
            /* User Login */
            login: {
                type: 'string',
                minLength: 4,
                maxLength: 16,
                required: true,
                notEmpty: true,
                unique: true
            }
        };      

        public static Model : any; // static store for data 

        constructor() {
            // there is not a concept of a static constructor in  
            // typescript, so static initialization code may be better else
            // where
        }       
    }

    // I've made this an anonymous function that is private to the module
    // It's executed immediately and initializes the "static" values of the 
    // class. this code could be moved into a static method of course and 
    // and called directly in the same way
    (()=> {
        // create the schema defined
        var schema : any = mongoose.Schema(Demo.LoginSchema);
        // add the statics before creating the model
        // http://mongoosejs.com/docs/guide.html#statics
        schema.statics.exists = () => {
           // here's a static method                    
        };
        // create the model
        Demo.Model = mongoose.Model('Demo', schema);

    })();
}

As there isn't a concept of a static constructor in JavaScript or Typescript, I've created an anonymous function inside of the MongooseDemo module to automatically initialize the static fields of the class. You could of course move the code around, but the general concept should work.

Or, you could just add the static methods directly to the model after it is created (again, in the anonymous method):

Demo.Model.exists2 = () => {
    // something different              
};

The actual code for adding a class method/static in Mongoose is very simple as it simply copies all functions (and properties) from the statics property of the Schema object instance to the new Model directly. So, the second example I've provided is functionally equivalent to the first way I proposed that is documented.

Upvotes: 2

Related Questions