Express / Mongoose路由器:'Cast to ObjectId因值而失败'未定义"在路径“_id” [英] Express/Mongoose Router: 'Cast to ObjectId failed for value "undefined" at path "_id"'

查看:106
本文介绍了Express / Mongoose路由器:'Cast to ObjectId因值而失败'未定义"在路径“_id”的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Express中有一个简单的API,允许用户将帖子标题发布和删除到MongoDB数据库中。出于某种原因,当我添加帖子标题,然后删除它时,我得到Cast to ObjectId failed for valueundefinedat path_id。

I have a simple API in Express that allows the user to 'post' and 'delete' a post title into a MongoDB database. For some reason, when I add a post title, then subsequently 'delete' it, I get the "Cast to ObjectId failed for value "undefined" at path "_id".

在我创建帖子后调用'delete'时似乎不存在_id。但是,当我刷新页面,然后单击删除时,它会完全正确地获取_id并删除输入。

It seems that the "_id" doesn't exist when I call 'delete' after I create the post. However, when I refresh the page, then click 'delete', it gets the "_id" perfectly fine and deletes the entry.

我在路由中做错了没有_id生成并且能够立即从帖子中提取?

Am I doing something wrong in the routing to not have the "_id" generate and able to be pulled from the post immediately?

module.exports = function(router) {

    var Post = require('../models/post.js');

    // middleware for the api requests
    router.use(function(req, res, next) {
        // do logging
        console.log('something is happening.');
        next(); // make sure we go to our next route and don't stop here
    });

    // test route to make sure everything is working (accessed at GET http://localhost:8080/api)

    router.get('/', function(req, res) {
        res.json({ message: 'hooray! welcome to our api!' });   
    });

    // all routes here

    // routes that end in /posts
    router.route('/posts')

        // create a Post (accessed at POST http://localhost:7777/api/posts)
        .post(function(req, res) {
            var post = new Post();
            post.postTitle = req.body.postTitle; // set the post name (comes from request) 
            console.log(post._id);

            // save post and check for errors
            post.save(function(err) {
                if (err)
                    return res.status(300).send(err);

                res.json({ message: 'post created!' });
            });
        })

        // get all Posts (accessed at GET http://localhost:7777/api/posts)
        .get(function(req, res) {
            Post.find(function(err, posts) {
                if (err)
                    return res.send(err);

                res.json(posts);
            });
        });

    // routes that end in /posts for specific id
    router.route('/posts/:post_id')

        // get the post with that id
        .get(function(req, res) {
            Post.findById(req.params.post_id, function(err, post) {
                if (err)
                    return res.send(err);

                res.json(post);
            });
        })

        // update the post with that id
        .put(function(req, res) {
            Post.findById(req.params.post_id, function(err, post) {
                if (err)
                    return res.send(err);

                post.postTitle = req.body.postTitle;

                // save the post
                post.save(function(err) {
                    if (err)
                        return res.send(err);

                    res.json({ message: 'post updated!' });
                });
            });
        })

        // deletes the post with that id
        .delete(function(req, res) {
            Post.findOne({
                _id:req.params.post_id
            }).remove(function(x){
                console.log("removed: ", x);
            });
        })

        .patch(function(req, res) {
            Post.findOne({
                _id: req.body._id
            }, function(err, doc) {
                for (var key in req.body) {
                    dock[key] = req.body[key];
                }
                doc.save();
                res.status(200).send();
            });
        });
}

/

function addPostItem(post){
        posts.push(post);
        triggerListeners();

        helper.post("/api/posts", post);
    }

function deletePost(post) {
        var index = posts.indexOf(post);
        console.log(post);
        posts.splice(index, 1);
        triggerListeners();

        helper.del('api/posts/' + post._id);
    }

/

var $ = require('jquery');

module.exports = {
    get: function(url) {
        return new Promise(function(success, error) {
            $.ajax({
                url: url,
                dataType: 'json',
                success: success,
                error: error
            });
        });
    },
    post: function(url, data) {
        return new Promise(function(success, error) {
            $.ajax({
                url: url,
                type: 'POST',
                data: data,
                success: success,
                error: error
            });
        });
    },
    patch: function(url, data) {
        return new Promise(function(success, error) {
            $.ajax({
                url: url,
                type: 'PATCH',
                data: data,
                success: success,
                error: error
            });
        });
    },
    del: function(url) {
        return new Promise(function(success, error) {
            $.ajax({
                url: url,
                type: 'DELETE',
                success: success,
                error: error
            });
        });
    }
};


推荐答案

在addPostItem中,将帖子添加到客户端列表中在进行POST调用之前的模型。您推送到posts数组的新创建的帖子将没有_id,因为它是在服务器上生成的而不是返回的。当您将服务器的未定义_id传递给服务器以获取此新帖子时,任何针对它的api调用都将失败并出现相同的错误。

In addPostItem you add the post to your client side list of models before you make the POST call. The newly created post you push onto the posts array will NOT have an _id, since it is generated on the server and not returned. As you pass the server an undefined _id to the server for this new post, any api calls against it will fail with the same error.

当您刷新页面并调用时你的get函数,你的所有帖子都有一个_id所以一切正常。

When you refresh the page and call your get function, all your posts have an _id so everything works correctly.

一个典型的模式是将创建的id(或整个帖子)返回给客户端在帖子创建,然后将其添加到您的项目数组(如下所示):

A typical pattern to follow would be to return created id (or the entire post) to the client on the post creation and then add that to your items array (something like this):

function addPostItem(post){
    triggerListeners();

    helper.post("/api/posts", post, function(res){
        posts.push(res.data);
    });
}

您还需要重写POST请求以返回创建的实体:

You'd also need to rewrite your POST request to return the created entity:

post.save(function(err) {
            if (err)
                return res.status(300).send(err, o);

            res.json(o);
        });

变化只是返回._id。另一种方法是在客户端创建id,但是你失去了原生mongo ObjectIds的一些优点。

A variation would be to return just the ._id. Another would be to create the id on the client side, but then you lose some of the advantages of the native mongo ObjectIds.

这篇关于Express / Mongoose路由器:'Cast to ObjectId因值而失败'未定义"在路径“_id”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆