mongodb 从mongoose传递“_id”时得到空字符串

gudnpqoy  于 2023-10-16  发布在  Go
关注(0)|答案(2)|浏览(111)

我正在使用node js、express和mongoose创建一个待办事项列表应用程序。
现在我正在尝试删除项目功能,使用表单中的复选框将item._id传递给express,
我的待办事项列表项的数据类型如下:

const todoSchema = new mongoose.Schema({
    context: String
});

todoList> db.todolists.find()
[
  {
    _id: ObjectId("65085d9277578bec0a1b9415"),
    context: 'angry',
    __v: 0
  },
  {
    _id: ObjectId("65085db177578bec0a1b9421"),
    context: 'extremely angry',
    __v: 0
  },

下面是我的EJS代码:

<form class="delete-form" action="/delete" method="POST">
    <div class="todobox">
        <input name="checkbox" value="<%=item._id%>" type="checkbox" onchange="this.form.submit()">
        <p>
            <%= item.context %>
        </p>
    </div>
</form>

下面是我的JS代码:

app.post("/delete", async(req, res) => {
    const checkedItem = req.body.checkbox;
    console.log(checkedItem);
    todolist.deleteOne({_id: checkedItem})
    .then(console.log(`Item (${checkedItem}) was deleted.`)).catch((err) => {
         console.log(err);
     });
    items = await todolist.find({}, { _id: 0, context: 1 });
    console.log(`now the to-do-list has ${items.length} items.`)
    res.redirect("/");
});

我打印出item._id(req.body.checkbox)。只得到一个空字符串“"。
捕获错误:

CastError: Cast to ObjectId failed for value "" (type string) at path "_id" for model "todolist"
    at ObjectId.cast (/Users/xuxiang/Documents/BACKEND/todoList-one/node_modules/mongoose/lib/schema/objectid.js:250:11)
    at SchemaType.applySetters (/Users/xuxiang/Documents/BACKEND/todoList-one/node_modules/mongoose/lib/schematype.js:1220:12)
    at SchemaType.castForQuery (/Users/xuxiang/Documents/BACKEND/todoList-one/node_modules/mongoose/lib/schematype.js:1632:15)
    at cast (/Users/xuxiang/Documents/BACKEND/todoList-one/node_modules/mongoose/lib/cast.js:356:32)
    at Query.cast (/Users/xuxiang/Documents/BACKEND/todoList-one/node_modules/mongoose/lib/query.js:4911:12)
    at Query._castConditions (/Users/xuxiang/Documents/BACKEND/todoList-one/node_modules/mongoose/lib/query.js:2232:10)
    at model.Query._deleteOne (/Users/xuxiang/Documents/BACKEND/todoList-one/node_modules/mongoose/lib/query.js:3021:8)
    at model.Query.exec (/Users/xuxiang/Documents/BACKEND/todoList-one/node_modules/mongoose/lib/query.js:4430:28)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
  stringValue: '""',
  messageFormat: undefined,
  kind: 'ObjectId',
  value: '',
  path: '_id',
  reason: BSONError: Argument passed in must be a string of 12 bytes or a string of 24 hex characters or an integer
      at new ObjectId (/Users/xuxiang/Documents/BACKEND/todoList-one/node_modules/bson/lib/bson.cjs:2055:23)
      at castObjectId (/Users/xuxiang/Documents/BACKEND/todoList-one/node_modules/mongoose/lib/cast/objectid.js:25:12)
      at ObjectId.cast (/Users/xuxiang/Documents/BACKEND/todoList-one/node_modules/mongoose/lib/schema/objectid.js:248:12)
      at SchemaType.applySetters (/Users/xuxiang/Documents/BACKEND/todoList-one/node_modules/mongoose/lib/schematype.js:1220:12)
      at SchemaType.castForQuery (/Users/xuxiang/Documents/BACKEND/todoList-one/node_modules/mongoose/lib/schematype.js:1632:15)
      at cast (/Users/xuxiang/Documents/BACKEND/todoList-one/node_modules/mongoose/lib/cast.js:356:32)
      at Query.cast (/Users/xuxiang/Documents/BACKEND/todoList-one/node_modules/mongoose/lib/query.js:4911:12)
      at Query._castConditions (/Users/xuxiang/Documents/BACKEND/todoList-one/node_modules/mongoose/lib/query.js:2232:10)
      at model.Query._deleteOne (/Users/xuxiang/Documents/BACKEND/todoList-one/node_modules/mongoose/lib/query.js:3021:8)
      at model.Query.exec (/Users/xuxiang/Documents/BACKEND/todoList-one/node_modules/mongoose/lib/query.js:4430:28),
  valueType: 'string',
  model: Model { todolist }
}

但是当我传递item.context到express时,它可以成功地得到正确的结果。对于_id和__v,我只能得到空字符串“"。
我也找了课程的讨论,问了ChatGPT,没有得到解决方案。
感谢您抽出宝贵时间提供帮助。

gzszwxb4

gzszwxb41#

感谢@尼姆罗德serok。我将删除方法从

app.post("/delete", async(req, res) => {
    ...
    items = await todolist.find({}, { _id: 0, context: 1 });
    ...
});

收件人:

app.post("/delete", async(req, res) => {
    ...
    items = await todolist.find({}, { _id: 1, context: 1 });
    ...
});

这影响了req.body,我现在可以获取_id了。但我仍然不明白为什么会出现这种情况。
如果有人有想法,请分享,谢谢@尼姆罗德serok,非常感谢。

jfewjypa

jfewjypa2#

主要问题是检查Item数据类型为String,在查询中使用时必须为ObjectId

// import 
    const { ObjectId } = require('mongodb')

app.post("/delete", async (req, res) => {
    const checkedItem = req.body.checkbox;
    // check checkedItem is valid objectID or not
    if (!ObjectID.isvalid(checkedItem)) 
        res.status(400).send({ code: 400, success: false, error: 'invalid id' })
    console.log(checkedItem);
    todolist.deleteOne({ _id: new ObjectID(checkedItem) })
        .then(console.log(`Item (${checkedItem}) was deleted.`)).catch((err) => {
            console.log(err);
        });
    const items = await todolist.find({}, { _id: 1, context: 1 });
    console.log(`now the to-do-list has ${items.length} items.`)
    res.redirect("/");
});

使用trycatch错误句柄的其他方法

// import 
    const { ObjectId } = require('mongodb')

    app.post("/delete", async (req, res) => {
        try {
            const checkedItem = req.body.checkbox;
            // check checkedItem is valid objectID or not
            if (!ObjectID.isvalid(checkedItem)) throw new Error('invalid id')
            console.log(checkedItem);
            todolist.deleteOne({ _id: new ObjectID(checkedItem) })
                .then(console.log(`Item (${checkedItem}) was deleted.`)).catch((err) => {
                    console.log(err);
                });
            const items = await todolist.find({}, { _id: 1, context: 1 });
            console.log(`now the to-do-list has ${items.length} items.`)
            res.redirect("/");
        } catch (error) {
            res.status(400).send({ code: 400, success: false, error: error.message })
            // or
            res.redirect("/400");
        }
    });

相关问题