简体   繁体   中英

Nested Schemas with Custom Objects in Mongoose for Node.js

I'm stuck on trying to use Mongoose for my simple Node.js app. I have created a couple custom objects in my object that basically implement a linked list data structure. Ive been able to save the objects successfully but the problem comes when I try to retrieve the object and call some of the methods that I have defined for it. I tried using Object.create() as a workaround but that did not work. Here is where the code fails:

UserObj.findOne( { username : username } ).exec( function(err, user) {
    if(err) {
        res.status(404).json( {success: false, message: "Database error"} );
        return;
    }
    if(user == null) {
        res.status(404).json( {success: false, message: "Username not Registered"} );
        return;
    }
    var sq = Object.create(MusicQueue, user.songQueue); // Not sure if im supposed to pass in MusicQueue or MusicQueue.prototype. Neither work though
    var pl = sq.getPlaylist();
    res.json({
        username : username,
        lastLogin : user.lastLogin,
        playlist : pl
    });
});

And here is the error I am getting:

    var pl = sq.getPlaylist();
                ^
TypeError: Object object has no method 'getPlaylist'

I do have that method defined as part of the prototype in the MusicQueue object ( MusicQueue.prototype.getPlaylist = function() {...}; ).

Any ideas on how I can get around this? Is there a way to cast user.songQueue from a generic object to a MusicQueue object and be able to call its instance methods?

Your User Schema should be defined like this:

userSchema.methods.getPlayList = function () {
  // * your function*, might need a callback if async...
};

var User = mongoose.Model('User', userSchema);

You can add a static method by using:

userSchema.statics.getUsersById = function(cb) {
  // * do something, and call cb when done, assuming it's async
};

You shouldn't use prototype to add methods. Mongoose will create an instance of the User model for result of calling findOne , and the getPlayList function, if properly defined as shown above, will be available (it was added to the prototype).

You mentioned in your comment a Linked List. You could do that like this:

var nodeSchema = mongoose.Schema({
    value: String,
    link: { type:  mongoose.Schema.Types.ObjectId, ref: 'Node' }
});

var Node = mongoose.Model('Node', nodeSchema);

I got around my particular situation by just creating copy(obj) methods to my objects that will take the objects returned by the findOne(...) method and copy the data in it to my objects. I've come up with other problems as a result of this but Im pretty sure they are unrelated to this question.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM