Search code examples
javascriptnode.jsexpressprototype-programming

ExpressJS require Javascript prototyped object in another file


I have a file that looks like this:

function UserController(){};

UserController.prototype = {
    theData: [],
    findAll: function(callback) {
        callback( null, this.theData );
     },
    findByID: function(id, callback) {
        var result = null;
        var count = theData.length;
        for (var i = 0; i < count; i++) {
            if (this.theData[i]._id == id) {
                result = this.theData[i];
                break;
            }
        }

        callback(null, result);
    },
    findByName: function(name, callback) {
        var result = null;
        var count = theData.length;

        for (var i = 0; i < count; i++) {
            if (this.theData[i].name == name) {
                result = this.theData[i];
                break;
            }
        };

        callback(null, result);
    },
    save: function(users, callback) {
        var user = null;

        if(typeof(users.length) === 'undefined') {
            users = [users];
        }

        var count = users.length;
        for (var i = 0; i < count; i++) {
            user = users[i];
            user._id = userCounter++;
            user.created_at = new Date();
        };

        callback(null, users);
    }
};

When I inspect the object (based off this), it tells me that it is function UserController(){} and has no methods or properties.

I've never used prototyping in Javascript and I can't see a thing wrong with what I've done here. It should be noted that I'm using this with Node.js and Expressjs but I don't believe that would be causing this problem.

EDIT
For brevity's sake I only posted what I was currently using, but I have also had the exact same problem using the file like this:

var userCounter = 1;

function UserController(){};

UserController.prototype.theData = [];

UserController.prototype.findAll = function(callback) {
    callback( null, this.theData );
};

UserController.prototype.findByID = function(id, callback) {
    var result = null;
    var count = theData.length;

    for (var i = 0; i < count; i++) {
        if (this.theData[i]._id == id)
        {
            result = this.theData[i];
            break;
        }
    };

    callback(null, result);
};

UserController.prototype.findByName = function(name, callback) {
    var result = null;
    var count = theData.length;

    for (var i = 0; i < count; i++) {
        if (this.theData[i].name == name) {
            result = this.theData[i];
            break;
        }
    };

    callback(null, result);
};

UserController.prototype.save = function(users, callback) {
    var user = null;

    if(typeof(users.length) === 'undefined') {
        users = [users];
    }

    var count = users.length;
    for (var i = 0; i < count; i++) {
        user = users[i];
        user._id = userCounter++;
        user.created_at = new Date();
    };

    callback(null, users);
};

One more edit
If I put this in the same file and Inspect it I get the results I would expect:

function Test(){};

Test.prototype = {
  theData: [],
  hello: function(){
    return "Hello World!";
  }
};

I don't see the difference and I don't see an error in my UserController code.


Solution

  • This link helped me figure it out.

    Turns out it WAS a problem with Expressjs. When using another file, you have to specifically call export on methods and objects you want to use with require. Or alternately, you can just call this.blahblah = function(){}; instead of export. Then when you require a file, it automatically turns it into an object.

    EDIT
    I found a different solution. It was as simple as changing my require call to look like this: var userController = new (require('./controllers/user').UserController);
    After that, I can use Prototyped functions and objects just fine which makes the file much more readable and easier to understand.