Reputation: 760
i am new using mongodb and i am practicing with ref and populate... but i have a silly problem.
i am receiving from my client a object like this.
{
"name": "Jhon"
"books": [
{
"title": "whatever",
"pages": 300
},
{
"title": "otherBook",
"pages": 450
}
]
}
So i have two schemas, authorSchema and booksSchema... so what i pretend is save the books and take the _id of each book to save the author with it.
My code in nodejs
authorCtrl.saveAuthor = (req, res) => {
var booksId= []
for (i = 0; i < req.body.books.length; i++) {
booksModel.create(req.body.books[i], function (err, book) {
booksId.push(book._id)
})
}
var author= {
name: req.body.name,
books: booksId
}
console.log(author) // here i check and books array is empty,
authorModel.create(author).then((authorSaved) => {
res.json(authorSaved)
}).catch(err => {
res.json(err)
})
}
i know it is an asynchronous problem... but how can i do it??.. or what is the best practice to ref collections?
/////EDIT//////
Here are my schemas
Authors Schema
const mongoose = require('mongoose')
const { Schema } = mongoose;
const authorsSchema = new Schema({
name: { type: String },
books: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'books'
}]
})
module.exports = mongoose.model('authors', authorsSchema);
Books Schema
const mongoose = require('mongoose')
const { Schema } = mongoose;
const booksSchema = new Schema({
title: { type: String },
pages: { type: Number }
})
module.exports = mongoose.model('books', booksSchema);
Upvotes: 0
Views: 4093
Reputation: 3185
You can do it with Javascript promises as below:
var booksId = [];
var promises = [];
req.body.books.forEach(element => {
promises.push(insertBook(element));
});
Promise.all(promises)
.then(function(data){
/* do stuff when success */
console.log('##GREAT##',booksId);
/*** INSERT ARRAY OF BOOK IDs INTO authorModel***/
})
.catch(function(err){
/* error handling */
});
function insertBook(element){
return new Promise(function(resolve, reject){
var book = new booksModel({
title: element.title,
page: element.page
});
book.save(function(err,data){
if(err){
console.log(err);
reject(err)
}else{
console.log('#success');
booksId.push(data._id)
resolve();
}
});
});
}
Upvotes: 0
Reputation: 848
Authors Schema:
const mongoose = require('mongoose')
const { Schema } = mongoose;
const authorsSchema = new Schema({
name: String,
books: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Book'
}]
})
module.exports = mongoose.model('Author', authorsSchema);
Books Schema:
const mongoose = require('mongoose')
const { Schema } = mongoose;
const booksSchema = new Schema({
title: String,
pages: Number,
})
module.exports = mongoose.model('Book', booksSchema);
NodeJS Code:
const author = {
name: req.body.name
}
AuthorModel.create(author, (error, createdAuthor)=>{
//handle error
BookModel.insertMany(req.body.books, function (err, createdbooks) {
// handle error
createdAuthor.books.push(createdbooks);
createdAuthor.save();
})
}
Upvotes: 1
Reputation: 907
Try this,
authorCtrl.saveAuthor = (req, res) => {
var booksId= [];
for (var i = req.body.books.length - 1; i >= 0; i--) {
booksModel.create(req.body.books[i], (err, book) => {
booksId.push(book._id);
if(i == 0) { // This if condition executes at the end of the for loop.
var author= {
name: req.body.name,
books: booksId
};
console.log(author);
authorModel.create(author).then((authorSaved) => {
res.json(authorSaved);
}).catch(err => {
res.json(err);
});
}
});
}
}
Hope it helps...
Upvotes: 0