Do you want to request a feature or report a bug?
bug
What is the current behavior?
Upon creating a new model instance (and likely when modifying one), passing false
(and some other alternatives) to a field that requires an array of sub-documents (schemas), causes a fatal ObjectParameterError.
If the current behavior is a bug, please provide the steps to reproduce.
The following program can be used to reproduce this:
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/temp', { useNewUrlParser: true });
const Child = new mongoose.Schema({});
const Parent = new mongoose.Schema({
children: {
type: [Child] // only happens for arrays of schemas
}
});
const ParentModel = mongoose.model('TestParent', Parent);
const model = new ParentModel({
children: false // also happens for: [false], 0, [0] and [false, 0], but NOT for e.g. [false, 0, true]
});
// error after calling save()
model.save(err => {
console.log(err.errors.children.message); // should instead give validation error message as such
});
This is the exception that gets thrown:
throw new ObjectParameterError(obj, 'obj', 'Document');
^
ObjectParameterError: Parameter "obj" to Document() must be an object, got false
at new ObjectParameterError (path\to\project\node_modules\mongoose\lib\error\objectParameter.js:25:11)
at EmbeddedDocument.Document (path\to\project\node_modules\mongoose\lib\document.js:68:11)
at EmbeddedDocument [as constructor] (path\to\project\node_modules\mongoose\lib\types\embedded.js:39:12)
at new EmbeddedDocument (path\to\project\node_modules\mongoose\lib\schema\documentarray.js:75:17)
at path\to\project\node_modules\mongoose\lib\schema\documentarray.js:187:26
at DocumentArray.SchemaType.doValidate (path\to\project\node_modules\mongoose\lib\schematype.js:829:12)
at DocumentArray.doValidate (path\to\project\node_modules\mongoose\lib\schema\documentarray.js:143:35)
at path\to\project\node_modules\mongoose\lib\document.js:1904:9
at _combinedTickCallback (internal/process/next_tick.js:131:7)
at process._tickCallback (internal/process/next_tick.js:180:9)
at Function.Module.runMain (module.js:695:11)
at startup (bootstrap_node.js:191:16)
at bootstrap_node.js:612:3
What is the expected behavior?
Instead of a fatal error being thrown, a validation error should be passed to the save callback. This is already the case for inputs such as true
, which simply give a message along the lines of Cast to Array failed for value "true" at path "children"
.
Please mention your node.js, mongoose and MongoDB version.
Node: 8.11.3, Mongoose: 5.3.12
Thanks for reporting, will fix ASAP
Seems like I got it again when using array push,
Chat.update( { _id: chatdata._id }, { $push: { message: data.message} }, (err, data) => {
console.log(err)
console.log(data)
})
got :
{ ObjectParameterError: Parameter "obj" to Document() must be an object, got 123213213
at new ObjectParameterError (C:\learning\chatappexample\server\node_modules\mongoose\lib\error\objectParameter.js:25:11)
at EmbeddedDocument.Document (C:\learning\chatappexample\server\node_modules\mongoose\lib\document.js:71:11)
at EmbeddedDocument [as constructor] (C:\learning\chatappexample\server\node_modules\mongoose\lib\types\embedded.js:41:12)
at new EmbeddedDocument (C:\learning\chatappexample\server\node_modules\mongoose\lib\schema\documentarray.js:76:17)
at DocumentArray.SchemaArray.castForQuery (C:\learning\chatappexample\server\node_modules\mongoose\lib\schema\array.js:312:13)
at DocumentArray.SchemaType.castForQueryWrapper (C:\learning\chatappexample\server\node_modules\mongoose\lib\schematype.js:1185:15)
at castUpdateVal (C:\learning\chatappexample\server\node_modules\mongoose\lib\helpers\query\castUpdate.js:427:17)
at walkUpdatePath (C:\learning\chatappexample\server\node_modules\mongoose\lib\helpers\query\castUpdate.js:261:22)
at castUpdate (C:\learning\chatappexample\server\node_modules\mongoose\lib\helpers\query\castUpdate.js:79:18)
at model.Query._castUpdate (C:\learning\chatappexample\server\node_modules\mongoose\lib\query.js:4064:10)
at castDoc (C:\learning\chatappexample\server\node_modules\mongoose\lib\query.js:4092:18)
at model.Query._updateThunk (C:\learning\chatappexample\server\node_modules\mongoose\lib\query.js:3399:17)
at model.Query.Query._execUpdate (C:\learning\chatappexample\server\node_modules\mongoose\lib\query.js:3460:23)
at process.nextTick (C:\learning\chatappexample\server\node_modules\kareem\index.js:369:33)
at process._tickCallback (internal/process/next_tick.js:61:11)
Sorry solved my bad.
Why do I need to use callbacks so the saved on the database?
An example does not save to database
Chat.updateOne( { _id: chatdata._id }, { $push: { message: {
from: data.from,
type: 'Text',
text: data.message
}}
}, { safe: true, upsert: true })
An example does success save to database
Chat.updateOne( { _id: chatdata._id }, { $push: { message: {
from: data.from,
type: 'Text',
text: data.message
}}
}, { safe: true, upsert: true }, (err, data) => console.log(data))
@mandaputtra you need to actually execute the query. That doesn't happen until you pass a callback, call Query#then()
, or call Query#exec()
. If you don't want to pass a callback or use then()
, use this:
Chat.updateOne( { _id: chatdata._id }, { $push: { message: {
from: data.from,
type: 'Text',
text: data.message
}}
}, { safe: true, upsert: true }).exec()