I am trying to fake non-array nested documents by creating a separate model for the embedded document, validating it and if the validation is successful, setting it as the main document's property.
In a POST /api/document route I am doing teh following:
var document = new DocumentModel({
title: req.body.title
});
var author = new AuthorModel({
name: req.body.author.name
});
author.validate( function( err ) {
if (!err) {
document.author = author.toObject();
} else {
return res.send( err, 400 );
}
});
console.log( document );
But it doesn't seem to work - console prints out the document without author. I am probably missing something very obvious here, maybe I need to do some kind of nested callbacks, or maybe I need to use a special setter method, like document.set( 'author', author.toObject() )... but I just can't figure it our on my own right now.
Looks like author.validate
is async so that your console.log(document);
statement at the bottom executes before the callback where you set document.author
. You need to put the processing that depends on document.author
being set inside of the callback.
It looks like the answer is to use a callback to set the document.author and to define author in the Schema.
Like @JohnnyHK pointed out, I can't log the document to console using my original code because the author.validate is async. So, the solution is to either wrap the console.log (and probably further document.save() inside the callback of author.validate()
It also seems that Mongoose does not "set" any properties for a model that are not defined in the Schema. Since my author is an object, I had to set the author field in the Schema to Mixed, like this.
The following code works:
var DocumentModel = new Schema({
title: { type: String, required: true },
author: {}
});
var AuthorModel = new Schema({
name: { type: String, required: true }
});
app.post("/api/documents", function(req, res) {
var document = new DocumentModel({
title: req.body.title
});
var author = new AuthorModek({
title: req.body.author.name
});
author.validate( function( err ) {
if (!err) {
document.author = author;
docment.save( function( err ) {
...
});
} else {
return res.send( err, 400 );
}
})
});