Mongoose updateMany not updating array

Issue

I have an application with 2 models: Student, Book (see below). Whenever a book is added, I would like it to be appended to the books array of every student model. The updateMany function of Mongoose should by my understanding do that, although it never updates the array.

POST function to create a new book object based on given ISBN and append it to every books array of the student model:

    if (req.isAuthenticated()) {
            if (req.body.ISBN && req.body.dueDate) {
                https.get('https://www.googleapis.com/books/v1/volumes?q=isbn:' + req.body.ISBN, function (hres) {
                    var body = "";
                    hres.on('data', function (chunk) {
                        body += chunk;
                    });
                    hres.on('end', function () {
                        var resp = JSON.parse(body);
                        const newBook = new book({
                            title: resp.items[0].volumeInfo.title,
                            length: resp.items[0].volumeInfo.pageCount,
                            author: resp.items[0].authors,
                            ISBN: req.body.ISBN,
                            finished: false,
                            dueDate: req.body.dueDate
                        });
                        newBook.save();
                        student.updateMany({},{$push: {books:newBook}})
                    });
                });
               
                res.redirect('/admin')
            }
            else {
                res.redirect('/newBook');
            }

    }
    else {
        res.redirect('/Login')
    }

Student model:

const mongoose = require('mongoose');
const bookSchema = require('./book').schema;

const studentSchema = new mongoose.Schema({
    name:{
        type: String,
        required: true
    },
    books:{
        type: [bookSchema]
    }
});

module.exports = mongoose.model("student", studentSchema); 

Book model:

 
const mongoose = require('mongoose');

const bookSchema = new mongoose.Schema({
    title:{
        type: String
    },
    length:{
        type:Number
    },
    author:{
        type:String
    },
    ISBN:{
        type:String
    },
    finished:{
        type:Boolean
    },
    dueDate:{
        type:String
    }
});

module.exports = mongoose.model("book", bookSchema);

Solution

student.updateMany({},{$push: {books:newBook}}) is the correct syntax but need the await word to properly works if you are using promises.

If you want to use callBacks you need to add the .exec() at the end of the operation so you are telling mongoose to run that command.

student.updateMany({},{$push: {books:newBook}}).exec((err,studentsUpdated)=>{
// respond here
})

Using async await (wich i recommend)

try {
const newBook = new book({
    title: resp.items[0].volumeInfo.title,
    length: resp.items[0].volumeInfo.pageCount,
    author: resp.items[0].authors,
    ISBN: req.body.ISBN,
    finished: false,
    dueDate: req.body.dueDate
});

const newBookAdded = await newBook.save();
const studentsUpdated = await student.updateMany({},{$push: {books:newBookAdded}})
    // Anwer here, if you console.log(studentsUpdated) you can check if the updateMany operation was correct
} catch (error) {
    // manage the error here
}

remmer you need to run to add the async word on the higher function to be able to use await, on you code shoud be here

async function (hres) 

Answered By – Fernando Jaimes

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published