Home > Software design >  backend node js with mongoDB, patch request does not update date type value
backend node js with mongoDB, patch request does not update date type value

Time:10-28

I use node.js to build the backend and persist the data in MongoDB. When I do a patch request, I can change the values of all the fields of other types except for the one of date type.

This is the backend code for the patch request.

router.patch('/:id', isLoggedIn, async (req, res) => {
    try {
        const updatedBooking = await Booking.updateOne(
            {_id: req.params.id},
            {
                $set: {userEmail: req.body.userEmail},  
                $set: {shiftDate: req.body.shiftDate},
                $set: {isMorningShift: req.body.isMorningShift}
            }
        );
        res.json(updatedBooking);
    } catch (err) {
        res.send({message: err});
    }
});

This is the database scheme:

const BookingSchema=mongoose.Schema({
    userEmail:{
        type:String,
        required:true
    },
    shiftDate:{
        type:Date,
        required:true
    },
    isMorningShift:{
        type: Boolean,
        required: true
    }
});

The objects in MongoDB look like this:

 {
    "_id": "61787183e67b6822180175f9",
    "userEmail": "[email protected]",
    "isMorningShift": false,
    "__v": 0,
    "shiftDate": "2066-06-23T00:00:00.000Z"
}

What might be the problem?

CodePudding user response:

Instead of multiple $set, update all the keys in one,

const updatedBooking = await Booking.updateOne(
            {_id: req.params.id},
            {
                $set: {
                       userEmail: req.body.userEmail,  
                       shiftDate: new Date(req.body.shiftDate),
                       isMorningShift: req.body.isMorningShift
               }
            }
        );

CodePudding user response:

@fractal397's answer will work fine. If you want a more cleaner code, you can use this.

const bookingId = req.params.id;
const payload =
   userEmail: req.body.userEmail,  
   shiftDate: new Date(req.body.shiftDate),
   isMorningShift: req.body.isMorningShift
}
const booking = await Booking.findByIdAndUpdate(bookingId, payload);

P.S. - After Mongoose 4.0, new value for findByIdAndUpdate has been changed to false by default. So in this operation, data will be updated in the database but it will return the old value booking. To get updated value in response too, you will have to do -

const booking = await Booking.findByIdAndUpdate(bookingId, payload, { new : true });

CodePudding user response:

Change the line:

$set: {shiftDate: req.body.shiftDate}

to

$set: {shiftDate: new Date(req.body.shiftDate)}

or

$set: {shiftDate: new Date()}  //for todays date in your local format

This works: I tested this with express like so:

app.get('/updateOne', async (req, res) => {
     //get data through query params in url
     const id = req.query.id;
     const date = req.query.date;
     //connect to db and collection     
     //1 connect
     //2 set db and collection
     const client = await MongoClient.connect(uri, { 
         useNewUrlParser: true, 
         useUnifiedTopology: true,
     });
     const collection = client.db("sample_airbnb").collection("listingsAndReviews");
    //update function for date field
    try {
        const updatedBooking = await collection.updateOne(
            {_id: id},
            {
                $set: {name: new Date(date)} //2066-06-23T00:00:00.000Z
            }
        );
        res.json(updatedBooking);
    } catch (err) {
        res.send({'message': err});
    }
})

Response:

{
    "acknowledged": true,
    "modifiedCount": 1,
    "upsertedId": null,
    "upsertedCount": 0,
    "matchedCount": 1
}

And updated data in Mongoscloud:

_id
:
"100009690"
name
:
2066-06-23T00:00:00.000 00:00

The I called the endpoint like so: http://localhost:5000/updateOne?id=100009690&date=2066-06-23T00:00:00.000Z and you see it's the same date format you say you expect.

Can you update your OP and show us the exact format you are passing in?? DO a console.log(req.body.shiftDate) on line 7 just before you pass it. I suspect here is where the issue is.

Obviously I shouldn't add dates to names field but this is purely for a quick test.

If updating multiple fields I'd with:

//update function
    try {
        const updatedBooking = await collection.updateOne(
            {_id: id},
            { 
                $set: {
                    name: name, 
                    email: email, 
                    lastShift: new Date(date)
                }
            }
        );
        res.json(updatedBooking);
    } catch (err) {
        res.send({'message': err});
    }
  • Related