Sergio Cano
Sergio Cano

Reputation: 760

saving ref of another document with mongoose and nodejs

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

Answers (3)

Jitendra
Jitendra

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

Arootin Aghazaryan
Arootin Aghazaryan

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

Alagarasan M
Alagarasan M

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

Related Questions