Search code examples
node.jsmongodbexpressmongoosemongoose-schema

Can't add object to MongoDB array inside a document


I'm building an API for my chat application and I wrote the endpoint below to save new messages in MongoDB.

The messages themselves are an array.

Testing this endpoint with Postman returns the newly created message in the response but the message is not added to my array of messages.

router.post('/:id/messages', async (request, response) => {
  const chatMessage = new Message({
    type: request.body.type,
    body: request.body.body,
    author: request.body.author
  });
  try {
    const newMessage = await chatMessage.save({ $push: { chatMessage } });
    response.status(201).json(newMessage);
  } catch (error) {
    response.status(400).json({ message: error.message });
  }
});

Here's my Mongoose schema for messages:

const mongoose = require('mongoose');

const messageSchema = new mongoose.Schema({
  type: {
    type: String
  },
  body: {
    type: String
  },
  author: {
    type: String
  },
  date: {
    type: Date,
    default: Date.now
  }
});

module.exports = mongoose.model('Message', messageSchema);

Any hints on what I've done wrong? Thank you so much! :-)

EDIT_ Mongo DB Sample


Solution

  • Please make these changes :

    chat schema file :

    /** messages schema w.r.t. messages field in chat document */
    const messageSchema = new mongoose.Schema({
        type: {
            type: String
        },
        body: {
            type: String
        },
        author: {
            type: String
        },
        date: {
            type: Date,
            default: Date.now
        }
    });
    
    /** Actual chat schema */
    const chatsSchema = new mongoose.Schema({
        id: Number,
        user1: String,
        user2: String,
        messages: [messageSchema]
    });
    
    function getChatsModel() {
        if (mongoose.models && mongoose.models.chats) {
            return mongoose.models.chats;
        }
        return mongoose.model('chats', chatsSchema, 'chats');
    }
    
    module.exports = getChatsModel();
    

    Code :

    /** Import chats model file here & also do require mongoose */
    router.post('/:id/messages', async (request, response) => {
        const chatMessage = {
            messages: {
                type: request.body.type,
                body: request.body.body,
                author: request.body.author
            }
        };
        try {
            const id = mongoose.Types.ObjectId(request.params.id);
            const dbResp = await Chats.findOneAndUpdate({ "_id": id }, { $push: chatMessage }, { new: true }).lean(true);
            if (dbResp) {
                // dbResp will be entire updated document, we're just returning newly added message which is input.
                response.status(201).json(chatMessage);
            } else {
                response.status(400).json({ message: 'Not able to update messages' });
            }
        } catch (error) {
            response.status(500).json({ message: error.message });
        }
    });