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.
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 themongoose
module). You will want to change your Mongoose function fromfindOne()
to simplyfind()
so thatmongoose
can return an array of docs with the properpostid
.
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 ...
});
}
);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With