Reputation: 2019
Having some issues!
The error is
local:
{ password: '$2a$08$kSflSzcciqWN78nfqAu/4.ZBZaXkqb19bEypeWcuSxg89yPNuijYO',
email: '***@gmail.com' } } has no method 'usersCharacters'
But it does have the method! I am not sure it is being exported properly. As far as I can tell I am doing it similarly to the other methods users have except here it doesn't seem to work.
user.js model file
....
module.exports = mongoose.model('User', UserSchema);
var User = mongoose.model('User', UserSchema);
/* method works :D ! -- not sure if over complicated though! */
UserSchema.methods.usersCharacters = function(email,cb){
User.findOne( {'local.email' : email }).exec(function(err, user){
if (err) console.log("shit");
var _return = [];
user.characters.forEach(function(err, i){
Character.findOne({ "_id" :user.characters[i] }).exec(function(err2, dude){
_return.push(dude);
/* Can't think of a smarter way to return :( */
if ( i == user.characters.length-1)
cb(_return);
});
});
});
};
routes.js
/* This doesn't work! I am wondering how I might be able to return this users characters --
*
* The error is here btw! TypeError: Cannot call method 'usersCharacters' of undefined -- line with character : ****
*/
app.get('/profile', isLoggedIn, function(req, res) {
var mongoose = require('mongoose');
var UserSchema = mongoose.model('User', UserSchema);
console.log(UserSchema);
// ERROR ON THIS LINE! : (
characters : req.user.usersCharacters(req.user.email, function(_characters){
console.log("list of characters: " + _characters);
return _characters;
res.render('profile.ejs', {
user : req.user, // get the user out of session and pass to template
characters : characters
});
here is a gist with more of my model file code:
https://gist.github.com/hassanshaikley/d4766251ec53feec8e84
Upvotes: 0
Views: 417
Reputation: 3929
JohnnyHK is correct that the order of creating a Mongoose model object is:
var UserSchema = new mongoose.Schema({...});
.UserSchema.methods.usersCharacters = ...
, as you have done.var User = mongoose.model('User', UserSchema);
module.exports = User;
However, that is not the immediate cause of your issue. You are calling .usersCharacters()
on an object called user
. While it may have key-value pairs identical to those of a Mongoose document object, it is not a Mongoose document object.
Instead, it is a generic Javascript object. You must first look up the corresponding Mongoose document object in your database, using the following:
User.findOne( {'local.email' : req.user.email } )).exec(function(err, userDoc){
if (err) console.log("shit");
var characters = req.user.usersCharacters(req.user.email, function(_characters){
console.log("list of characters: " + _characters);
return _characters;
});
res.render('profile.ejs', {
user : req.user, // get the user out of session and pass to template
characters : characters
});
});
Note that the req.user
object passed to res.render()
will only contain the properties sent in the request, which may be different from those in the userDoc
object.
Do be aware, however, that I am currently having trouble accessing instance methods of documents returned from using .findOne()
. If you run into that problem, you can check out my thread here: Instance methods not defined for Mongoose findOne() query result?
Upvotes: 0
Reputation: 311865
Methods that you add to UserSchema
after creating the User
model from it, won't be available on User
model instances.
So create the method before creating the User
model:
UserSchema.methods.usersCharacters = function(email,cb){ ... };
var User = mongoose.model('User', UserSchema);
module.exports = User;
On a related note, only the first call to mongoose.model('User', UserSchema)
processes the schema to create the 'User'
model. Subsequent calls ignore the UserSchema
parameter and return the existing model.
Upvotes: 1