【问题标题】:[CastError: Cast to ObjectId failed for value "undefined" at path "_id"[CastError: 路径“_id”处的值“未定义”转换为 ObjectId 失败
【发布时间】:2018-03-17 19:10:15
【问题描述】:

当尝试在我的删除(或更新)路线中使用 req.params.id 时,我收到了上述消息。这让我困惑了一段时间,我确信我的路线/对象在某个地方犯了错误。

将应用程序从 res.render("/campgrounds/ + req.params.id); 更改为 - res.render("/campgrounds");解决了这个问题,但不会像我希望的那样重新加载同一页面。从 req.params.id 访问露营地路线时,我无法理解为什么应用程序返回 undefined。

var express= require("express");
var router = express.Router();
var Comment = require("../models/comment");
var Campground = require("../models/campgrounds");


// COMMENTS EDIT ROUTE



router.get("/campgrounds/:id/comments/:comment_id/edit", function(req, res){

            Comment.findById(req.params.comment_id, function(err, foundComment){
                if(err){
                    console.log(err)
                } else {
                    res.render("comments/edit", {campground_id: req.params.id, comment: foundComment})
                }
            })
        })


// comment update 

//campgrounds/:id/comments/:comment_id
router.put("/:comment_id", function(req, res){
    Comment.findByIdAndUpdate(req.params.comment_id, req.body.comment, function(err, updatedComment){
        if(err){
            console.log(err)
        } else {
            // KNOWN BUG - /campgrounds/ + req.params.id will return cast to boject failed for value undefined at path _id. having the app redirect to all campgrounds page as a work around
            res.redirect("/campgrounds");
        }
    })
})

// DELETE ROUTER
router.delete("/:comment_id", function(req, res){
    Comment.findByIdAndRemove(req.params.comment_id, function(err){
        if(err){
            res.redirect("back");
        } else {

            res.redirect("/campgrounds/" + req.params.id);
        }
    })
})



function isLoggedIn(req, res, next){
    if(req.isAuthenticated()){
     return next();   
    } else {
        res.redirect("/login");
    }
}

module.exports = router;

【问题讨论】:

  • 你能给我请求的 url 你是如何从 server@Andy 访问 url 的
  • app.listen(process.env.PORT, process.env.IP, function(){ console.log("App is running"); })

标签: javascript node.js mongodb mongoose


【解决方案1】:

这个问题的最佳解决方案是通过清理它添加的空白空间来重新格式化_id(在我的例子中来自我的模板“x.ejs”中的一个表单)

const to_remove = req.body.checkbox;//id from template is wrong
const listname = req.body.check_list_name;

let **to_rem_cured** = to_remove.replace(/\s/g,'');

List.findOneAndUpdate({name:listname},{'$pull':{list:{_id: **to_rem_cured**  }}},function(err,doc){
  if(!err){
    console.log(doc);

    res.redirect("/"+listname);
  }
  else{
    console.log(err);

  }
});

【讨论】:

    【解决方案2】:

    好的,我最近遇到了同样的问题。我尝试在整个互联网上寻找解决方案,但没有得到任何有用的答案。

    然后我尝试仔细查看“CastError”,发现我从“req.params.id”获取的 ID 前面有一个额外的空白。

    例如:我的 ID 不是“5bed4f6276c4920db404eb25”,而是“5bed4f6276c4920db404eb25”。我不知道(还不)为什么我会得到带有额外空白的 id,但我认为空白一定是问题所在。

    所以我用 javascript 替换函数去除了空格的 ID,如下所示:

        var curid = req.params.id;
        curid = curid.replace(/\s/g,'');
    

    它成功了!

    所以不是

        Campground.findByIdAndUpdate(req.params.id, req.body.campground, function(err, updatedCamp){..}
    

    现在使用:

        Campground.findByIdAndUpdate(curid, req.body.campground, function(err, updatedCamp){..}
    

    所以,你必须全部替换

        req.params.id
    

    在您的代码块中使用

        curid
    

    你可以走了!

    这是整个代码块供您参考:

    router.put("/:id", function(req, res){
    var curid = req.params.id;
    curid = curid.replace(/\s/g,'');
    
    Campground.findByIdAndUpdate(curid, req.body.campground, function(err, updatedCamp){
        if(err){
            console.log(err);
            res.redirect("/campgrounds");
        } else{
            //redirect somewhere (show page)
            res.redirect("/campgrounds/" + curid);        
        }
    });
    

    【讨论】:

      【解决方案3】:

      我遇到了同样的问题,这是由于路线顺序造成的。我将显示路线移动到索引路线下方,因为“它流动得更好”,但这破坏了代码,并且混淆了它,因为我认为路线顺序很重要。如果您重新排序,请确保您的路线从应用程序的角度来看是有意义的

      【讨论】:

        【解决方案4】:

        我认为你的问题是你没有将comment_id从html发送到控制器尝试打印req.params.comnent_id

        那就试试这个

            var express= require("express");
            var router = express.Router();
            var Comment = require("../models/comment");
            var Campground = require("../models/campgrounds");
        
        
            // COMMENTS EDIT ROUTE
        
        
        
            router.get("/campgrounds/:id/comments/:comment_id/edit", function(req, res){
            console.log("params.comment_id",params.comment_id);
           if(req.params.comment_id){
              Comment.findById(req.params.comment_id, function(err, foundComment){
                            if(err){
                                console.log(err)
                            } else {
                                res.render("comments/edit", {campground_id: req.params.id, comment: foundComment})
                            }
                      }else {
                                res.render("comments/edit", {campground_id: req.params.id, comment: foundComment})
                            }
        
                        })
                    })
        

        【讨论】:

        • 所以这是我设置的 edit.ejs 文件中的 html:<form action="/campgrounds/<%= campground._id %>/comments/<%= comment._id %>?_method=put" method="POST"> 我已将您的代码添加到路由并将comment._id 更新为comment_id。我认为这就是您将html传递给控制器​​的意思吗?当我这样做时,我得到一个参考错误,指出未定义 comment_id。
        • 把这个console.log("params.comment_id",params.comment_id);改成console.log("params.comment_id",req.params.comment_id);
        • 添加了你的路由和函数,仍然得到:消息:'Cast to ObjectId failed for value "undefined" at path "_id"'。在 cloud9 中工作,如果这有影响的话。
        【解决方案5】:

        确保您在评论表单中输入了字段名称“id”(或在 ajax 请求中输入了“id”)。

        router.put("/:comment_id", function(req, res){
            const id = req.params.id;
            console.log(id);
            Comment.findByIdAndUpdate(req.params.comment_id, req.body.comment, function(err, updatedComment){
                if(err){
                    console.log(err)
                } else {
                    res.redirect("/campgrounds/" + id);
                }
          })
        })

        【讨论】:

        • 我的输入字段设置如下:
          对不起,我的格式很糟糕时间试图弄清楚如何在堆栈中格式化 cmets。
        • 你是在建议我应该在我的输入中输入 name="id" 吗? @Đức Lê Minh
        • 我认为您应该在评论中存储 campground_id。然后你可以重定向到“campgrounds/”+updatedComment.campground_id
        猜你喜欢
        • 2014-06-20
        • 2016-11-11
        • 2017-03-26
        • 2017-05-26
        • 2020-05-20
        • 2019-01-06
        • 2016-05-06
        • 2021-07-04
        • 2021-06-05
        相关资源
        最近更新 更多