Search code examples
node.jsmongodbexpressmongoose

Finding wrong entry in Mongo database when trying to update entry


I'm using Node with Express and MongoDB. In this application I'm trying to find and update an entry (will be called event from now on) in the data base, based on an id. The id is provided in the request body as tempEventInfoForEdit which is an object containing the field _id among other things.

If there is only one event registered on a user, editing the event works fine.

If there are several events, the code doesn't find the correct event matching the provided id.

EDIT: Instead it creates a new entry with the new information, instead of actually updating the original. Any time you try and update an event it is only the new event updating. For example: We have Event1 and Event2. Trying to edit Event1 to change venue to 'Home' creates Event3 with the venue 'Home'. Trying to edit Event2 with venue 'Away' updates Event3 to have venue 'Away'.

Console.logging show this:

tempEventInfoForEdit._id 64a3ef985ef705278a198396
selectedEvent._id new ObjectId("64a3eeb65ef705278a198346")
req.body = tempEventInfoForEdit {
  _id: '64a3ef985ef705278a198396',
  host: 'elinelin',
  hostId: '63e4face7f8e01e7bff3ae09',
  venue: 'Hemma',
  county: 'Dalarnas county',
  eventDate: '2023-07-05T10:08:07.000Z',
  eventTime: '14:08',
  game: 'Frostpunk: The Board Game',
  openSpots: 1,
  totalSpots: 2,
  description: 'It will be fun',
  image: 'https://s3-us-west-1.amazonaws.com/5cc.images/games/uploaded/1592244158290',
  isFull: false,
  pendingPartyMembers: [],
  createdAt: '2023-07-04T10:08:24.744Z',
  __v: 0
}
import { User, Event } from '../../Models';

export const updateEvent = async (req, res) => {
  const {tempEventInfoForEdit} = req.body;
  console.log('tempEventInfoForEdit', tempEventInfoForEdit)
  if (tempEventInfoForEdit) {         
    try {
      const selectedEvent = await Event.findOne({ id: tempEventInfoForEdit._id });
      const user = await User.findOne({ accessToken: req.header("Authorization") });
      const host = await User.findOne({ _id: selectedEvent.hostId });
      if (user.username === host.username) {
        if (selectedEvent) {
          console.log('tempEventInfoForEdit._id', tempEventInfoForEdit._id)
          console.log('selectedEvent._id', selectedEvent._id)
          const eventUpdatedFromModel = await Event.findOneAndUpdate(tempEventInfoForEdit._id,
            { $set: {
                venue: tempEventInfoForEdit.venue,
                county: tempEventInfoForEdit.county,
                game: tempEventInfoForEdit.game,
                openSpots: tempEventInfoForEdit.openSpots,
                totalSpots: tempEventInfoForEdit.totalSpots,
                description: tempEventInfoForEdit.description,
                eventDate: tempEventInfoForEdit.eventDate,
                eventTime: tempEventInfoForEdit.eventTime,
                eventName: tempEventInfoForEdit.eventName,
                image: tempEventInfoForEdit.image
              } 
            }
          );
          if (eventUpdatedFromModel) {
            const updatedHostingEvents = await User.findOneAndUpdate({ _id: user._id, 'hostingEvents._id': selectedEvent._id },
            { $set: { 
              'hostingEvents.$.venue': tempEventInfoForEdit.venue,
              'hostingEvents.$.county': tempEventInfoForEdit.county,
              'hostingEvents.$.game': tempEventInfoForEdit.game,
              'hostingEvents.$.openSpots': tempEventInfoForEdit.openSpots,
              'hostingEvents.$.totalSpots': tempEventInfoForEdit.totalSpots,
              'hostingEvents.$.description': tempEventInfoForEdit.description,
              'hostingEvents.$.eventDate': tempEventInfoForEdit.eventDate,
              'hostingEvents.$.eventTime': tempEventInfoForEdit.eventTime,
              'hostingEvents.$.eventName': tempEventInfoForEdit.eventName,
              'hostingEvents.$.image': tempEventInfoForEdit.image
            }}, { new: true } );

            if (updatedHostingEvents) {
              res.status(200).json({
                success: true,
                response: {
                  eventUpdatedFromModel: eventUpdatedFromModel,
                  hostingEvents: updatedHostingEvents.hostingEvents,
                  message: "The event has been updated"
                }
              });
            }  
          };
        } else {
          res.status(400).json({
            success: false,
            response: {
              message: "Event was not found"
            }
          });
        };
      } else {
        res.status(401).json({
          success: false,
          response: {
            message: "Unauthorized attempt to edit event"
          }
        });
      }
    } catch (err) {
      res.status(500).json({
        success: false,
        response: {
          message: err.stack
        }
      });
    };
  }
};

Any ideas why this is happening?


Solution

  • What caused the problem was me forgetting to specify the field and just using the key.

    Adding the missing _ to id as user20042973 pointed out in the comment and updating the code to the below solved the problem:

    const eventUpdatedFromModel = await Event.findOneAndUpdate{ _id: tempEventInfoForEdit._id },