TypeError: Cannot call method 'call' of undefined
at Array.MongooseArray._cast (/Users/bodo/Documents/Repositories/EnabreNode/node_modules/mongoose/lib/types/array.js:78:15)
at Object.map (native)
at Array.MongooseArray.push (/Users/bodo/Documents/Repositories/EnabreNode/node_modules/mongoose/lib/types/array.js:187:23)
at module.exports (/Users/bodo/Documents/Repositories/EnabreNode/accounts/routes/me.js:29:27)
at callbacks (/Users/bodo/Documents/Repositories/EnabreNode/node_modules/express/lib/router/index.js:160:37)
at Promise.module.exports (/Users/bodo/Documents/Repositories/EnabreNode/middleware/load_user.js:15:13)
at Promise.addBack (/Users/bodo/Documents/Repositories/EnabreNode/node_modules/mongoose/lib/promise.js:128:8)
at Promise.EventEmitter.emit (events.js:96:17)
at Promise.emit (/Users/bodo/Documents/Repositories/EnabreNode/node_modules/mongoose/lib/promise.js:66:38)
at Promise.complete (/Users/bodo/Documents/Repositories/EnabreNode/node_modules/mongoose/lib/promise.js:77:20)
I actually want to built a quite simple schema:
{
username: "bodo",
email: "info@example.com",
contacts: [{
user: { username: "john", email: "john@google.com" },
messages: [
{
sender: { username: "bodo", email: "info@example.com" },
receiver: { username: "john", email: "john@google.com" },
body: "How are you these days?"
},
{
sender: { username: "john", email: "john@google.com" },
receiver: { username: "bodo", email: "info@example.com" },
body: "I am totally fine?"
}
]
}]
};
The contacts attribute contains a contacts subdocument which holds the user object of the actual contact (as reference) and later on some meta data like hasAcceptedContactRequest, contactSince, etc.
Additionally I also save messages subdocs which are from a chat. These message subdocs contain the message as body attribute and who has send or received it. The sender and receiver are again references to a full user object which can be populated.
So much in theory. I now have created these schemas:
UserSchema
var Mongoose = require('mongoose');
var ContactSchema = require('./contact');
var UserSchema = new Mongoose.Schema({
username: {
type: String,
index: { unique: true, sparse: true },
required: true, lowercase: true, trim: true
},
email: {
type: String,
index: { unique: true, sparse: true },
required: true, lowercase: true, trim: true
},
contacts: [ContactSchema]
});
module.exports = Mongoose.model('User', UserSchema, 'Users');
ContactSchema
var Mongoose = require('mongoose');
var MessageSchema = require('./message');
var ContactSchema = new Mongoose.Schema({
user: {
ref: "User",
type: Mongoose.Schema.Types.ObjectId
},
messages: [MessageSchema]
});
module.exports = ContactSchema;
MessageSchema
var MessageSchema = new Mongoose.Schema({
body: {
type: String
},
sender: {
ref: "User",
type: Mongoose.Schema.Types.ObjectId
},
receiver: {
ref: "User",
type: Mongoose.Schema.Types.ObjectId
}
});
module.exports = ContactSchema;
That is the route
app.put('/me', loadUser, function(req, res, next) {
var user = req.user;
var body = req.body;
if (body.contacts) {
body.contacts.forEach(function(contact) {
user.contacts.push({ user: contact });
});
}
console.log(req.user);
user.save(function(err, user) {
if (err) return next(err);
res.send(200);
});
});
Solution:
As johnyHK mentioned there was a problem using the module system of node. I have accidentally
exported the schemas as models. You now see the corrected examples above. So they should work.
Assuming the order of your schema definitions is the same in your code, you need to reorder them so that the referenced schemas are fully defined when used.
So that would be:
MessageSchemaContactSchemaUserSchema