在路径“_id”处,对于值“0”,转换为ObjectId失败

时间:2017-06-08 16:44:08

标签: javascript angularjs node.js mongodb mongoose

我开始使用Node.js为我的网络应用程序构建我的REST Api。到目前为止,我在邮差测试它,它的工作原理。例如,我插入此链接 http://localhost:3000/news 并通过给我一个json响应来工作。

            [
          {
            "_id": "593978f7995e071df49b08d8",
            "updatedAt": "2017-06-08T16:19:03.551Z",
            "createdAt": "2017-06-08T16:19:03.551Z",
            "title": "Camping in the City and this year.",
            "image": "img/news1.jpg",
            "description": "From the Municipality of Larissa, and in particular the Social Policy Advocacy and the Department of Sports and Culture and Social Policy, it is announced that following the absolutely successful 'Camping in the City' program, organized last summer, the Municipality of Larissa in collaboration with the citys stakeholders, the program Will be implemented this year as well.",
            "__v": 0,
            "comments": [
              {
                "updatedAt": "2017-06-08T16:19:03.547Z",
                "createdAt": "2017-06-08T16:19:03.547Z",
                "rating": 5,
                "comment": "Λατρεύω το camping!!!",
                "author": "Theo",
                "_id": "593978f7995e071df49b08db"
              },
              {
                "updatedAt": "2017-06-08T16:19:03.550Z",
                "createdAt": "2017-06-08T16:19:03.550Z",
                "rating": 5,
                "comment": "Καλά μιλάμε τέλειο!!!",
                "author": "Chris",
                "_id": "593978f7995e071df49b08da"
              },
              {
                "updatedAt": "2017-06-08T16:19:03.550Z",
                "createdAt": "2017-06-08T16:19:03.550Z",
                "rating": 2,
                "comment": "Βαρετό.",
                "author": "Σοφία.",
                "_id": "593978f7995e071df49b08d9"
              }
            ]
          }
        ]

我的路线如图所示

                    var express = require('express');
                var bodyParser = require('body-parser');
                var mongooser = require('mongoose');

                var News = require('../models/news')

                var newsRouter = express.Router();

                newsRouter.use(bodyParser.json());

                newsRouter.route('/')
                .get(function(req,res,next){
                    News.find({},function(err,news){
                       if(err) throw err;
                       res.json(news);    
                    });
                })

                .post(function(req,res,next){
                   News.create(req.body,function(err,news){
                      if(err) throw err;

                      console.log('News created')
                      var id = news._id;

                      res.writeHead(200,{
                         'Content-Type':'text/plain' 
                      }); 
                       res.end('Added the article with id: ' + id);
                   })
                })
                .delete(function (req, res, next) {
                        News.remove({}, function (err, resp) {
                            if (err) throw err;
                            res.json(resp);
                        });
                });

                newsRouter.route('/:newsId')
                .get(function (req, res, next) {
                        News.findById(req.params.newsId, function (err, news) {
                            if (err) throw err;
                            res.json(news);
                        });
                    })

                .put(function (req, res, next) {
                        News.findByIdAndUpdate(req.params.newsId, {
                            $set: req.body
                        }, {
                            new: true
                        }, function (err, news) {
                            if (err) throw err;
                            res.json(news);
                    });
                })

                .delete(function (req, res, next) {
                        News.findByIdAndRemove(req.params.newsId, function (err, resp) {
                            if (err) throw err;
                            res.json(resp);
                    });
                });

                newsRouter.route('/:newsId/comments')
                    .get(function (req, res, next) {
                        News.findById(req.params.newsId, function (err, news) {
                            if (err) throw err;
                            res.json(news.comments);
                        });
                    })

                    .post(function (req, res, next) {
                        News.findById(req.params.newsId, function (err, news) {
                            if (err) throw err;
                            news.comments.push(req.body);
                            news.save(function (err, news) {
                                if (err) throw err;
                                console.log('Updated Comments!');
                                res.json(news);
                            });
                        });
                    })

                    .delete(function (req, res, next) {
                        News.findById(req.params.newsId, function (err, news) {
                            if (err) throw err;
                            for (var i = (news.comments.length - 1); i >= 0; i--) {
                                news.comments.id(news.comments[i]._id).remove();
                            }
                            news.save(function (err, result) {
                                if (err) throw err;
                                res.writeHead(200, {
                                    'Content-Type': 'text/plain'
                                });
                                res.end('Deleted all comments!');
                            });
                        });
                    });

                newsRouter.route('/:newsId/comments/:commentId')
                    .get(function (req, res, next) {
                        News.findById(req.params.newsId, function (err, news) {
                            if (err) throw err;
                            res.json(news.comments.id(req.params.commentId));
                        });
                    })

                    .put(function (req, res, next) {
                        // We delete the existing commment and insert the updated
                        // comment as a new comment
                        News.findById(req.params.newsId, function (err, news) {
                            if (err) throw err;
                            news.comments.id(req.params.commentId).remove();
                            news.comments.push(req.body);
                            news.save(function (err, news) {
                                if (err) throw err;
                                console.log('Updated Comments!');
                                res.json(news);
                            });
                        });
                    })

                    .delete(function (req, res, next) {
                        News.findById(req.params.newsId, function (err, news) {
                            news.comments.id(req.params.commentId).remove();
                            news.save(function (err, resp) {
                                if (err) throw err;
                                res.json(resp);
                            });
                        });
                    });

                module.exports = newsRouter;

由于这已经准备就绪,我想使用Angular.js从客户端读取这个json。所以我创建了一家工厂。

angular.module('larissaApp')
               .constant('baseURL', 'http://localhost:3000/')
               .factory('newsFactory',['$resource', 'baseURL', function($resource,baseURL) {

               var newsfac = {};

               newsfac.getNews = function(){
                    return $resource(baseURL+"news/:id",null,  {'update':{method:'PUT' }});
               };

               return newsfac;       

        }])

和控制器。

.controller('IndexController',['$scope','newsFactory','AnnouncementsFactory','EventsFactory',function($scope,newsFactory,AnnouncementsFactory,EventsFactory){

                 $scope.message="Loading ...";

                 $scope.newsOne = newsFactory.getNews().get({id:0})
                    .$promise.then(
                        function(response){
                            $scope.newsOne = response;

                        },
                        function(response) {
                            $scope.message = "Error: "+response.status + " " + response.statusText;
                        }
                 );


                 $scope.newsTwo = newsFactory.getNews().get({id:1})
                    .$promise.then(
                        function(response){
                            $scope.newsTwo = response;
                            $scope.showDish = true;
                        },
                        function(response) {
                            $scope.message = "Error: "+response.status + " " + response.statusText;
                        }
                 );


                 $scope.newsThree = newsFactory.getNews().get({id:2})
                    .$promise.then(
                        function(response){
                            $scope.newsTwo = response;

                        },
                        function(response) {
                            $scope.message = "Error: "+response.status + " " + response.statusText;
                        }
                 );


                 $scope.eventOne = EventsFactory.getEvents(0);


                 $scope.eventTwo = EventsFactory.getEvents(1);


                 $scope.eventThree = EventsFactory.getEvents(2);



                 $scope.announcementOne = AnnouncementsFactory.getAnnouncement(0);
                 $scope.announcementTwo = AnnouncementsFactory.getAnnouncement(1);
                 $scope.announcementThree = AnnouncementsFactory.getAnnouncement(2);


    }])

就像你现在一样,我只是动态地阅读新闻。但是我在控制台中收到此错误。

                events.js:160
                  throw er; // Unhandled 'error' event
                  ^
            CastError: Cast to ObjectId failed for value "0" at path "_id" for model "News"
                at MongooseError.CastError (C:\Users\Theodosios\Desktop\larissa-node\larissa
            App\rest-server\node_modules\mongoose\lib\error\cast.js:26:11)
                at ObjectId.cast (C:\Users\Theodosios\Desktop\larissa-node\larissaApp\rest-s
            erver\node_modules\mongoose\lib\schema\objectid.js:149:13)
                at ObjectId.SchemaType._castForQuery (C:\Users\Theodosios\Desktop\larissa-no
            de\larissaApp\rest-server\node_modules\mongoose\lib\schematype.js:1023:15)
                at ObjectId.castForQuery (C:\Users\Theodosios\Desktop\larissa-node\larissaAp
            p\rest-server\node_modules\mongoose\lib\schema\objectid.js:189:15)
                at cast (C:\Users\Theodosios\Desktop\larissa-node\larissaApp\rest-server\nod
            e_modules\mongoose\lib\cast.js:232:32)
                at Query.cast (C:\Users\Theodosios\Desktop\larissa-node\larissaApp\rest-serv
            er\node_modules\mongoose\lib\query.js:2933:12)
                at Query.findOne (C:\Users\Theodosios\Desktop\larissa-node\larissaApp\rest-s
            erver\node_modules\mongoose\lib\query.js:1394:10)
                at Function.findOne (C:\Users\Theodosios\Desktop\larissa-node\larissaApp\res
            t-server\node_modules\mongoose\lib\model.js:1360:13)
                at Function.findById (C:\Users\Theodosios\Desktop\larissa-node\larissaApp\re
            st-server\node_modules\mongoose\lib\model.js:1288:15)
                at C:\Users\Theodosios\Desktop\larissa-node\larissaApp\rest-server\routes\ne
            wsRouter.js:41:14
                at Layer.handle [as handle_request] (C:\Users\Theodosios\Desktop\larissa-nod
            e\larissaApp\rest-server\node_modules\express\lib\router\layer.js:95:5)
                at next (C:\Users\Theodosios\Desktop\larissa-node\larissaApp\rest-server\nod
            e_modules\express\lib\router\route.js:137:13)
                at Route.dispatch (C:\Users\Theodosios\Desktop\larissa-node\larissaApp\rest-
            server\node_modules\express\lib\router\route.js:112:3)
                at Layer.handle [as handle_request] (C:\Users\Theodosios\Desktop\larissa-nod
            e\larissaApp\rest-server\node_modules\express\lib\router\layer.js:95:5)
                at C:\Users\Theodosios\Desktop\larissa-node\larissaApp\rest-server\node_modu
            les\express\lib\router\index.js:281:22
                at param (C:\Users\Theodosios\Desktop\larissa-node\larissaApp\rest-server\no
            de_modules\express\lib\router\index.js:354:14)
            npm ERR! code ELIFECYCLE
            npm ERR! errno 1
            npm ERR! rest-server@0.0.0 start: `node ./bin/www`
            npm ERR! Exit status 1
            npm ERR!
            npm ERR! Failed at the rest-server@0.0.0 start script 'node ./bin/www'.
            npm ERR! Make sure you have the latest version of node.js and npm installed.
            npm ERR! If you do, this is most likely a problem with the rest-server package,
            npm ERR! not with npm itself.
            npm ERR! Tell the author that this fails on your system:
            npm ERR!     node ./bin/www
            npm ERR! You can get information on how to open an issue for this project with:
            npm ERR!     npm bugs rest-server
            npm ERR! Or if that isn't available, you can get their info via:
            npm ERR!     npm owner ls rest-server
            npm ERR! There is likely additional logging output above.

            npm ERR! A complete log of this run can be found in:
            npm ERR!     C:\Users\Theodosios\AppData\Roaming\npm-cache\_logs\2017-06-08T16_1
            9_28_708Z-debug.log

如何修复此错误?正如我所说,邮递员一切正常。

谢谢,

西奥。

更新

我在我的:/ newsId路线上做了一些小改动。基本上我将req.params.newsId转换为猫鼬类型。

newsRouter.route('/:newsId')
                .get(function (req, res, next) {

                        News.findById(req.params.newsId = mongoose.Types.ObjectId(req.params.newsId), function (err, news) {
                            if (err) throw err;
                            res.json(news);
                            console.log(req.body._id);
                        });
                    })

但现在我收到了这个错误。

2angular.js:12587 GET http://localhost:3000/news/0 500 (Internal Server 
Error)

index.html#!/:1 XMLHttpRequest cannot load http://localhost:3000/news/0. No 
'Access-Control-Allow-Origin' header is present on the requested resource. 
Origin 'http://127.0.0.1:61612' is therefore not allowed access. The 
response had HTTP 

1 个答案:

答案 0 :(得分:0)

我几天前也遇到了同样的错误,所以这是我的建议:

“0”是一个字符串,因此不是ObjectId,因此您可以尝试将其转换为一个字符串。找到包含您的ID“0”的变量,并将其转换为ObjectId,如下所示:

req.body._id = mongoose.Types.ObjectId(req.body._id);

req.params.newsId = mongoose.Types.ObjectId(req.params.newsId);

但是你有另一个问题:0不能是ObjectId,因为ObjectId必须是12个字节的单个字符串或24个十六进制字符的字符串。所以上述方法不起作用。 您可能没有收到正确的身份证。

希望它有所帮助,

致以最诚挚的问候,

更新

您收到错误500因为您的更新错误,您无法在方法req.body._id内为News.findById分配值。您应该执行以下操作:

newsRouter.route('/:newsId')
  .get(function (req, res, next) {
    req.params.newsId = mongoose.Types.ObjectId(req.params.newsId);
    News.findById(req.params.newsId, function (err, news) {
      if (err) throw err;
      console.log(req.body._id);
      res.json(news);
    });
  });