backend node js with mongoDB, patch request does not update date type value

707 Views Asked by At

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?

3

There are 3 best solutions below

2
stackymacky obroedar On

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});
    }
0
fractal397 On

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
               }
            }
        );
0
Pankaj Tanwar On

@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 });