简体   繁体   中英

mongoose push into array not working

I am making a Library Management app with Nodejs at the backend and MongoDB as the database. It is a simple express server and uses mongoose library. The client who has to issue a book sends a POST request and its record is added to the database. Here is the model of my Logs:

var Logs = mongoose.model('Logs', {


bookid: {
    type: Number,
    required: true,
    minlength: 1
  },
  status: {
    type: String,
    required: true,
    minlength: 1,
    trim: true
  },
  details: [{
    issuedby: {
      type: String,
      trim: true
    },
    issuedate: {
      type: Date,
    },
    returndate: {
      type: Date
    }
  }]
});  

Now when the POST request is received, I try to change the "status" of book from "Available" to "Issued", and add the record of the customer in "details" field. Here is the code:

app.post('/issueBook', (req,res) => {
  console.log(req.body);
  Logs.findOne({bookid: req.body.bookid}).then((doc) => {
    if(doc.status == "Available"){
      var detail = {};
      detail.issuedby = req.body.issueTo;
      detail.issuedate = new Date();
      Logs.findOneAndUpdate({bookid: req.body.bookid}, {$set: {status:"Issued"}}, {$push: {details:detail}}, {upsert: true}, function(err,doc) {
        if(err) {
          console.log("Couldn't issue");
          res.status(400).send(err);
        } else{
          res.send("OK");
        }
      });
    } else{
      res.send({
        status: "Error",
        reason: "Book already issued !"
      });
    }
  }, (e) => {
    res.send({
      status: "Error",
      reason: "Invalid Book ID !"
    });
  });
});  

The server crashes when i send this POST request. On checking the database, i found that the "status" field successfully changes from "Available" to "Issued", but no record was inserted in "details". Is there something wrong with my query? Please suggest corrections to my code.
This is the snippet of error while crashing:

Error in Terminal can be seen below:

在此处输入图片说明

Change this code


Logs.findOneAndUpdate({bookid: req.body.bookid}, {$set: {status:"Issued"}}, {$push: {details:detail}}, {upsert: true}, function(err,doc)

To this


Logs.findOneAndUpdate({bookid: req.body.bookid}, {$set: {status:"Issued"}}, {$push: {details:detail}}, {upsert: true}).then((result) => {
  console.log(result)
}.catch((error) => {
  console.log(error)
}

Please tell me what the console.log(error) will return you and according to that error message, I am able to give you a final answer.

Update


You might try the following code block. This code will look for a Log with the Id you'll provide in the request.body and with a status of Available. If this query finds the Log it will send it back in the response. If not, it'll throw an error that it didn't find it.

app.post('/api/issueBooking', (request, response) => {

Log.findOneAndUpdate({
         bookid: request.body.bookid,
         status: "Available"
       }, {
         $set: {
           status: "Issued"
         }
       }, {
         $push: {
           "details": {
             issueby: "issueByHere",
             issuedate: "issueDateHere",
             returndate: "returnDateHere"
           }
         },
         {
           upsert: true
         }).then((log) => {

         if (!log) {
           return Promise.reject({
             status_code: 404,
             message: "Log not found."
           })
         }

         response.status(200).send("OK");

       }).catch((error) => {
         response.status(error.status_code).send(error.message);
      })
  });

The error is probably because you are not updating the details field correctly. As I can see in your schema, you have defined details to be [] but you are updating it with an object {} . You have to fix that. But also I think you can make the script better. The statement:

Logs.findOneAndUpdate({bookid: req.body.bookid}, {$set: {status:"Issued"}}, {$push: {details:detail}}, {upsert: true}, function(err,doc) {

seems redundant. You already have the doc you need to update in:

Logs.findOne({bookid: req.body.bookid}).then((doc) => {

After you get this doc , just modify whatever you want akin to a javascript object and do doc.save

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM