我正在try 建立一个使用Express JS和reactJS的消息传递站点. 我目前正在开发该网站的消息发送功能.我的目标是,当用户单击Reaction页面上的Send按钮时,它向Express后端发出POST请求,后者将消息数据推送到我的MongoDB Altlas集合中正确用户的"Messages"array.问题是我不知道如何将消息推送到正确用户的数组中,因为它与集合中的其他数据嵌套在一起. 有谁可以帮我?

以下是我坚持使用的index.js快速代码:

const userSchema = new mongoose.Schema({
    name: String,
    password: String,
    profilePicture: String,
    contacts: [{name: String, 
        profilePicture: String, 
        messages: [{sender: String, message: String}], 
    }]
});
const User = new mongoose.model('User', userSchema);


app.post("/send-message", (req, res) => {
    var sender = req.body.sender;
    var recv = req.body.recv;
    var message = req.body.msg
    User.findOne({name: sender}).then(user => {
        user.contacts.forEach(contact => {
            if (contact.name === recv){
                // newMessage is the object I would like to push to the 
                // messages array for the sender.
                var newMessage = {sender: "me", message: message};
            }
        });
    }).then(() => {
        User.findOne({name: recv}).then(user => {
            user.contacts.forEach(contact => {
                if (contact.name === sender){
                    // newMessage is the object I would like to push to 
                    // the messages array for the receiver.
                    var newMessage = {sender: "them", message: message};
                }
            });
        }).then(res.send("Message Sent!"))
        .catch(e => {console.log("2: " + e); res.send("Error!")});
    }).catch(e => {console.log("1: " + e); res.send("Error!")});
});

下面是我对SendMessage函数的react 代码:

const [usrn, setUsrn] = React.useState("<Username>");
const [pass, setPass] = React.useState("<Password>");
const [messageThread, setMessageThread] = React.useState({});
const [message, setMessage] = React.useState("");

const SendMessage = () => {
        axios.post(props.apiUrl + "send-message/", {sender: usrn, recv: 
                   messageThread.contact, msg: message})
        .then(res => {
            console.log(res.data);
            setMessage("");
        });
    }

推荐答案

您可以使用findOneAndUpdateUser$push的新消息对象 Select 到正确的数组中.通过 Select contacts.name,您可以使用MongoDB $位置运算符,它将只推送到匹配的数组元素.

此示例使用async/await模式和try/catch模式,以便更轻松地处理错误.你有多个then.catch个街区,在我的经验中这是一个螺旋式下降.

app.post("/send-message", async (req, res) => { //< Mark callback as async
    try{
        const sender = req.body.sender;
        const recv = req.body.recv;
        const message = req.body.msg
        // Add message to sender
        const userSender = await User.findOneAndUpdate({ //< use await pattern
            name: sender,
            'contacts.name': recv
        },{
            $push:{
                'contacts.$.messages': { sender: "me", message: message }    
            }
        }, {new: true});
        if(!userSender){ //< If no sender was found return error
            return res.status(400).json({
                message: 'Sender not found'
            })
        }
        // Add message to receiver
        const userReceiver = await User.findOneAndUpdate({ //< use await pattern
            name: recv,
            'contacts.name': sender
        },{
            $push:{
                'contacts.$.messages': { sender: "them", message: message }
            }
        }, {new: true});
        if(!userReceiver){ //< If no receiver was found return error
            return res.status(400).json({
                message: 'Receiver not found'
            })
            // Handle deletion of object in sender
        }
        return res.status(201).json({
            message: 'Messages Saved!'
        })
    }catch(err){
        console.log(err);
        return res.status(500).json({
            message: 'Error on server.'
        })
    }
});

Node.js相关问答推荐

如何使用updateMany()和Node.js的方法?

如何在Angular jest测试中调用Nodejs的垃圾收集? node v20的测试速度慢且内存泄漏

如何设置 Puppeteer Select 器的唯一性?

如何使用mongoose引用不在项目中的模型

如何使用包含条件正确分页的 sequelize 查询?

在将用作 nodejs/expressjs 中的中间件的函数中使用 keycloak.protect()

ESLint:TypeError:this.libOptions.parse 不是函数

配额超出了每分钟的 Sheets API 写入请求数. node .js

当我们有esnext时,为什么我们需要nodenext typescript 编译器选项?

如果我使用像 express 这样的 node 服务器,是否需要 webpack-dev-server

在 PassportJS 中使用多种本地策略

使用 nvm-windows 时更新 npm

Chrome 浏览器未将 if-modified-since 标头发送到服务器

socket.io 发出回调合适吗?

NODEJS 进程信息

为什么 Node 控制台不显示功能代码?

遍历 NodeJS 中的一系列日期

Node.js 17.0.1 Gatsby 错误-数字信封 routine ::不支持 ... ERR_OSSL_EVP_UNSUPPORTED

Node.js - 判断是否安装了模块而不实际需要它

AWS Lambda:如何将秘密存储到外部 API?