MEAN堆栈:推入MongoDB模式的第一个对象导致RangeError

时间:2017-10-13 17:51:46

标签: javascript angularjs node.js mongodb

编辑:我已经意识到这是挂在线上的#res; res.json(评论);"我的角度ui路线。仍不确定原因。

我在这里完成了教程:https://thinkster.io/tutorials/mean-stack。这可能与教程有点过时的事实有关。我已将我的代码的当前状态上传到http://github.com/orieporter/flappernews

它是一个简单的reddit克隆网络应用程序,用于发布链接,评论和提升它们。我得到一个" RangeError:超出最大调用堆栈大小"每次我将第一条评论添加到帖子时都会出错。后续评论没有问题。当我重新启动节点服务器并重新加载页面时,打破服务器的注释就在那里。任何人都可以帮我找到问题吗?

完整错误:

events.js:160
  throw er; // Unhandled 'error' event
  RangeError: Maximum call stack size exceeded
at model.Document.$toObject (c:\Users\source\repos\flapper-news\node_modules\mongoose\lib\document.js:1962:24)
at model.Document.toJSON (c:\Users\source\repos\flapper-news\node_modules\mongoose\lib\document.js:2300:15)
at clone (c:\Users\source\repos\flapper-news\node_modules\mongoose\lib\utils.js:252:18)
at cloneArray (c:\Users\source\repos\flapper-news\node_modules\mongoose\lib\utils.js:362:14)
at clone (c:\Users\source\repos\flapper-news\node_modules\mongoose\lib\utils.js:247:12)
at cloneObject (c:\Users\source\repos\flapper-news\node_modules\mongoose\lib\utils.js:343:13)
at clone (c:\Users\source\repos\flapper-news\node_modules\mongoose\lib\utils.js:260:16)
at model.Document.$toObject (c:\Users\source\repos\flapper-news\node_modules\mongoose\lib\document.js:2009:13)
at model.Document.toJSON (c:\Users\source\repos\flapper-news\node_modules\mongoose\lib\document.js:2300:15)
at clone (c:\Users\source\repos\flapper-news\node_modules\mongoose\lib\utils.js:252:18)
at cloneObject (c:\Users\source\repos\flapper-news\node_modules\mongoose\lib\utils.js:343:13)
at clone (c:\Users\source\repos\flapper-news\node_modules\mongoose\lib\utils.js:260:16)
at model.Document.$toObject (c:\Users\source\repos\flapper-news\node_modules\mongoose\lib\document.js:2009:13)
at model.Document.toJSON (c:\Users\source\repos\flapper-news\node_modules\mongoose\lib\document.js:2300:15)
at clone (c:\Users\source\repos\flapper-news\node_modules\mongoose\lib\utils.js:252:18)
at cloneArray (c:\Users\source\repos\flapper-news\node_modules\mongoose\lib\utils.js:362:14)
at clone (c:\Users\source\repos\flapper-news\node_modules\mongoose\lib\utils.js:247:12)

相关HTML:

<form ng-submit="addComment()" style="margin-top:30px;">
    <h3>Add a new comment</h3>
    <div class="form-group">
        <input type="text" class="form-control" placeholder="Comment" ng-model="body"></input>
    </div>
    <button type="submit" class="btn btn-primary">Post</button>
</form>

角度控制器功能:

$scope.addComment = function () {
    if ($scope.body === '') { return; }
    posts.addComment(post._id, {
        body: $scope.body,
        author: 'user'
    },
    $scope.post);
    $scope.body = '';
};

角度工厂功能:

o.addComment = function (id, comment, post) {
    return $http.post('/posts/' + id + '/comments', comment).then(function (response) {
        post.comments.push(response.data);
        return response.data;
    });
};

相关快递路线:

router.post('/posts/:post/comments', function (req, res, next) {
    var comment = new Comment(req.body);
    comment.post = req.post;

    comment.save(function (err, comment) {
        if (err) { return next(err); }

        req.post.comments.push(comment);
        req.post.save(function (err, post) {
            if (err) { return next(err); }

            res.json(comment);
        });
    });
});

评论架构:

var CommentSchema = new mongoose.Schema({
    body: String,
    author: String,
    upvotes: {type: Number, default: 0},
    post: {type: mongoose.Schema.Types.ObjectId, ref: 'Post' }
});

发布架构:

var PostSchema = new mongoose.Schema({
    title: String,
    link: String,
    upvotes: {type: Number, default: 0},
    comments: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Comment' }]
});

2 个答案:

答案 0 :(得分:0)

这是因为res.json(comment);正在尝试对您在var comment = new Comment(req.body);

上创建的评论对象实例进行字符串化

但&#34;字符串化&#34;由于评论对象的大小(它太大而且不必进行字符串化),因此进程显然悬而未决。

您应该用

之类的内容替换res.json(comment);

res.json({ status: "success" });

答案 1 :(得分:0)

我遇到了同样的问题并且花了我一些时间(几个小时!)的控制台日志调试,谷歌搜索,以及thinkster懒散的发型来试图弄清楚发生了什么。请注意,我是所有这一切的新手,所以把我的脑袋缠在一切可能是最大的挑战。

经过进一步检查,我将原因缩小到res.json(comment)行以及创建新的评论路由逻辑(routes / index.js)。

逻辑上,当我需要的只是注释对象id时,我不明白为什么整个注释对象被推送到post comments数组。所以我很自然地想到为什么不只是传递评论对象id(comment._id)并看看会发生什么。还有沃拉,它奏效了。不再是RangeError: Maximum call stack size exceeded

所以这可能会解决这个问题,但我奇怪的顽固自我想知道为什么那么重要?为什么它只发生在帖子的第一条评论上,但在其他条款上工作正常?

router.post('/posts/:post/comments', auth, function(req, res, next) {
  var comment = new Comment(req.body);
  comment.post = req.post._id; // <-- originally 'req.post'
  comment.author = req.payload.username;

  comment.save(function(err, comment){
    if(err){ return next(err); }

    req.post.comments.push(comment._id);  // <-- originally 'comment'
    req.post.save(function(err, post) {
      if(err){ return next(err); }

      res.json(comment);
    });
  });
});

我想如果mongoose只需要发布和评论ID而不是整个对象,那么为什么不保存ID。存储完整的对象似乎会导致某种无限循环我相信在响应期间会导致调用堆栈错误。也许是因为两个对象互相引用?但话说回来,我不确定这一切是如何真正有效的,所以如果有任何专家能够解决这些问题,请做。但这应该解决这个问题,并希望能够帮助其他人。我应该提一下,这是他们提供的实际Flapper新闻代码中的错误。我通过下载完成的源代码并运行它来找到它。