Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/36.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 无法读取属性';标题';未定义的。快车_Node.js_Mongodb_Express - Fatal编程技术网

Node.js 无法读取属性';标题';未定义的。快车

Node.js 无法读取属性';标题';未定义的。快车,node.js,mongodb,express,Node.js,Mongodb,Express,嗨,我正在开发nodejs express应用程序。我有个例外,不知道为什么。对我来说一切似乎都很完美。我的例外情况如下所示: 500 TypeError: C:\Nodejs\NodejsBlog\apps\blog/views/postdetail.jade:23<br/> 21| .col- md-12 <br/> 22| .posts <br/> > 23| h3= post.title <br/> 24| p=post.body

嗨,我正在开发nodejs express应用程序。我有个例外,不知道为什么。对我来说一切似乎都很完美。我的例外情况如下所示:

 500 TypeError: C:\Nodejs\NodejsBlog\apps\blog/views/postdetail.jade:23<br/> 21| .col- md-12 <br/> 22| .posts <br/> > 23| h3= post.title <br/> 24| p=post.body <br/> 25| p tag:      <br/> 26| i=post.tag <br/><br/>Cannot read property 'title' of undefined
21| .col-md-12
22| .posts
> 23| h3= post.title
24| p=post.body
25| p tag:
26| i=post.tag
Cannot read property 'title' of undefined
at eval (eval at (C:\Nodejs\NodejsBlog\node_modules\jade\lib\jade.js:152:8), :221:59)
at C:\Nodejs\NodejsBlog\node_modules\jade\lib\jade.js:153:35
at Object.exports.render (C:\Nodejs\NodejsBlog\node_modules\jade\lib\jade.js:197:10)
at Object.exports.renderFile (C:\Nodejs\NodejsBlog\node_modules\jade\lib\jade.js:233:18)
at View.exports.renderFile [as engine] (C:\Nodejs\NodejsBlog\node_modules\jade\lib\jade.js:218:21)
at View.render (C:\Nodejs\NodejsBlog\node_modules\express\lib\view.js:76:8)
at Function.app.render (C:\Nodejs\NodejsBlog\node_modules\express\lib\application.js:504:10)
at ServerResponse.res.render     (C:\Nodejs\NodejsBlog\node_modules\express\lib\response.js:798:7)
at C:\Nodejs\NodejsBlog\apps\blog\routes.js:64:14
at callbacks (C:\Nodejs\NodejsBlog\node_modules\express\lib\router\index.js:164:37)
我的看法是:

extends ../../../views/bloglayout
block js
script(type='text/javascript')
    $(function() {
        $("#commentform" ).submit(function( event ) {
            alert( "Handler for .submit() called." );
            $.ajax({
                url: '/Post/Comment/',
                type: "POST",
                data: $('#commentform').serialize(),
                success: function(response){
                alert('Yorum Kaydedildi');
                }
            }); 
            event.preventDefault();
        });
    });

block content
.row
    .col-md-12
        .posts
            h3=post.title
            p=post.body
            p tag:
                i=post.tag
            p Anahtar Kelimeler:
                b=post.keywords
        .row
            .col-md-4
                h5 Yorum Yap
                  form#commentform(role='form',action='/Post/Comment', method='post')
                            input(type='hidden',name='comment[postid]',value=postdata._id)
                        .form-group
                            input.form-control(type='email',name='comment[email]',placeholder='E-posta adresi')
                        .form-group
                            input.form-control(type='text',name='comment[website]', placeholder='Website')
                        .form-group
                            textarea.form- control(type='text',name='comment[content]', placeholder='Yorum')
                        button.btn.btn-  default(type='submit') Ekle
                -comments.forEach(function(comment) {
                .well
                    p
                        b=comment.content
                    p=comment.email
                -})

我还检查了我的mongodb。有数据。我不知道为什么'title'属性是'undefined'我不知道。

这是一个竞赛条件问题。从MongoDB提取的两个函数是异步的,因此对
res.render()
的调用发生在DB返回每个函数各自回调中的数据之前。您需要嵌套每个函数,以便它们能够访问适当的上下文。见下文:

app.get('/Post/:id', function (req, res, next){
  Post.findOne({_id:req.params.id},function(err, postData){
    if (err) return next(err);  

    Comment.findOne({postid:req.params.id},function(err, comments){
      if (err) return next(err);

      return res.render(__dirname+"/views/postdetail",{
        title: 'adfasdf',
        stylesheet: 'postdetail',
        post:postData,
        comments:comments
      });

    });
  });
});
然而,你可以看到,当你越来越远地筑巢时,这会变得非常混乱。为了防止这种情况,可以使用控制流库,如

旁注: Jade希望迭代
注释
数组,并从MongoDB返回单个文档(假设您使用的是
mongoose
模块)。您需要将Mongoose函数从
findOne()
更改为简单的
find()
,以便
Mongoose
可以返回具有正确
postid
的文档数组

编辑:
Vinayak Mishra也正确地指出,您可以使用Express的路由中间件作为在路由中施加控制流的一种方式。以下是一个例子:

// Use the app.param() method to pull the correct post doc from the database.
// This is useful when you have other endpoints that will require work on
// a Post document like PUT /post/:postid
app.param('postid', function (req, res, next, id) {

  Post.findById(id, function (err, post) {
    if (err) return next(err);
    if (!post) return next('route');
    req.post = post;
  });

});

app.get('/post/:postid',
  // -- First route middleware grabs comments from post doc saved to req.post
  function (req, res, next) {
    Comment.find({ postid: req.post.id }, function (err, comments) {
      if (err) return next(err);
      req.comments = comments;
      next();
    });
  },
  // -- This route middleware renders the view
  function (req, res, next) {
    res.render('/postDetail', {
      // ... list locals here ...
    });
  }
);

从db获取数据的两个例程是异步例程,因此在您触发
res.render()
时不会调用它们的回调。您需要等待查询返回结果,然后调用render

在准备呈现帖子之前,您可以使用中间件按顺序获取帖子和评论

这里有一个例子

app.get('/Post/:id', fetchPost, fetchComments, renderPost, handleErrors);

function fetchPost(req, res, next) {
  Post.findOne({
    _id: req.params.id
  }, function (err, docs) {
    if (!err && docs) {
      console.log('Gönderi bulundu');
      req.postdata = docs;
      next();
    } else {
      console.log('Gönderi bulunamadı');
      next(err || new Error('No such post: ' + req.params.id));
    }
  });
}

function fetchComments(req, res, next) {
  Comment.findOne({
    postid: req.params.id
  }, function (err, comments) {
    if (!err) {
      console.log('Yorum bulundu');
      req.postComments = comments || [];
      next();
    } else {
      console.log('Yorum bulunamadı');
      next(err);
    }
  });
}

function renderPost(req, res, next) {
  res.locals.post = req.postdata;
  res.locals.comments = req.postComments;
  res.locals.title = 'adfasdf - anything that fits';
  res.locals.stylesheet = 'postdetail';
  return res.render(__dirname + '/views/postdetail');
}

function handleErrors(err, req, res, next) {
  // You'll get here only if you recieved an error in any of the previous middlewares
  console.log(err);

  // handle error and show nice message or a 404 page
  res.locals.errmsg = err.message;
  res.render(__dirname + '/views/error');
}

如果您无法遵循上述代码中的任何内容,请告诉我。

您也可以为视图文件添加代码吗?添加了问题视图。您确定日志中没有
'Gönderi Bulunaadı'
?看起来
docs
变量是
null
…我敢肯定。在我的日志中没有“Gönderi Bulumanadı”。谢谢,问题解决了。我还更新了我的代码。现在使用find()方法获取注释。你是对的。
app.get('/Post/:id', fetchPost, fetchComments, renderPost, handleErrors);

function fetchPost(req, res, next) {
  Post.findOne({
    _id: req.params.id
  }, function (err, docs) {
    if (!err && docs) {
      console.log('Gönderi bulundu');
      req.postdata = docs;
      next();
    } else {
      console.log('Gönderi bulunamadı');
      next(err || new Error('No such post: ' + req.params.id));
    }
  });
}

function fetchComments(req, res, next) {
  Comment.findOne({
    postid: req.params.id
  }, function (err, comments) {
    if (!err) {
      console.log('Yorum bulundu');
      req.postComments = comments || [];
      next();
    } else {
      console.log('Yorum bulunamadı');
      next(err);
    }
  });
}

function renderPost(req, res, next) {
  res.locals.post = req.postdata;
  res.locals.comments = req.postComments;
  res.locals.title = 'adfasdf - anything that fits';
  res.locals.stylesheet = 'postdetail';
  return res.render(__dirname + '/views/postdetail');
}

function handleErrors(err, req, res, next) {
  // You'll get here only if you recieved an error in any of the previous middlewares
  console.log(err);

  // handle error and show nice message or a 404 page
  res.locals.errmsg = err.message;
  res.render(__dirname + '/views/error');
}