expression式/ Mongoose路由器:'投射到ObjectId失败的价值“未定义”的path“_id”

我在Express中有一个简单的API,允许用户将post标题“发布”并“删除”到MongoDB数据库中。 出于某种原因,当我添加一个post标题,然后“删除”它,我得到了“path”_id“未定义的”投向ObjectId失败的值“。

当我创buildpost后,我称之为“删除”,似乎“_id”不存在。 但是,当我刷新页面,然后单击“删除”,它获得“_id”完美罚款,并删除条目。

我在路由中做错了没有“_id”生成,并能立即从post中拉出?

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调用之前,将该post添加到模型的客户端列表中。 你推到posts数组上的新创build的post将不会有_id,因为它是在服务器上生成的,而不是返回的。 当你传递服务器一个未定义的_id到这个新post的服务器时,任何针对它的api调用都会失败,并出现相同的错误。

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

遵循的典型模式是在创build后将创build的id(或整个post)返回给客户端,然后将其添加到您的items数组中(如下所示):

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

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

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

一个变化就是只返回._id。 另一种方法是在客户端创build这个id,但是这样会丧失本地mongo ObjectIds的一些优点。