Cannot read property 'title' of undefined. Express

express, mongodb, node.js

Solution

This is a race condition issue. The two functions that pull from MongoDB are asynchronous and so the call to `res.render()` happens before the DB returns the data in each function's respective callback. You need to nest each function so that they have access to the proper context. See below:

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
      });

    });
  });
});

However, you can see how this can get pretty messy as you nest further and further. To prevent this, you can use a control flow library like caolan/async

Side Note:

You're Jade is looking to iterate over a `comments` array and you are returning a single doc from MongoDB (assuming you are using the `mongoose` module). You will want to change your Mongoose function from `findOne()` to simply `find()` so that `mongoose` can return an array of docs with the proper `postid`.

Edit:

Vinayak Mishra is also correct in pointing out that you can use Express' routing middleware as a way to impose control flow within a route. Here is an example:

// 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 ...
    });
  }
);

Problem

Hi im developing nodejs express app. I am getting exception and dont know why. Everything seem to perfect for me. My exception is shown below: ``` 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) ``` And here is the app.post code: ``` app.get('/Post/:id',function(req,res){ var postdata; var comments; Post.findOne({_id:req.params.id},function(err, docs){ if(docs) { postdata=docs; console.log('Gönderi bulundu'); console.log(docs); console.log(postdata); console.log(postdata.title); } else { console.log('Gönderi bulunamadı'); } }); Comment.findOne({postid:req.params.id},function(err, docs){ if(docs) { console.log('Yorum bulundu'); console.log(docs); } else { comments=docs; console.log('Yorum bulunamadı'); } }); return res.render(__dirname+"/views/postdetail",{ title: 'adfasdf', stylesheet: 'postdetail', post:postdata, comments:comments }); }); ``` And my view: ``` 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 -}) ``` Also i checked my mongodb. There is data. I dont know why 'title' property is 'undefined' have no idea.

Original source