I'm making a first node/express/mongo/handlebars project and am struggling with the HTML output side. I did have it working briefly but broke something whilst developing the code.
I'm not sure if I just fluked my initial output and am looking for advice on how to best approach the problem or if it's a simple mistake. I have added entry to mongo with no problems and am retrieving the data ok, but can't consistently output the results.
router.get('/:chanName', function(req, res, next) {
if (req.params.chanName != 'add') {
let myData = {};
MongoClient.connect(url, { useNewUrlParser: true }, (err, client) => {
if (err) { return console.log('Unable to connect to MongoDB'); }
//get result from db
client.db('tube').collection('channel-reviews').find({'channel': req.params.chanName}).toArray(function(err, result) {
if (err) throw err;
myData = result[0];
// myData is populated object here
});
// myData is empty object here
client.close();
res.render('review');
});
} else {
res.render('add');
}
});
The URL is used as a param to retrieve a mongo entry which I'm then trying to render as a list with the following template
<ul>
<li>{{ myData.channel }}</li>
<li>{{ myData.chanURL }}</li>
<li>{{ myData.score }}</li>
<li>{{ myData.title }}</li>
<li>{{ myData.content }}</li>
</ul>
Have I just put something in the wrong place or is it something more fundamental (like final code is executed long before the data can be retrieved and processed) and requires using Promises etc ?
As mentioned on https://expressjs.com/en/api.html#res.render res.render() function takes local variables for the view as second parameter, hence you need to pass the object to the function res.render()
Going by the template, the function call would be like
res.render('review',{myData:myData});
This should work fine with your template provided the mydata object has all those properties(channel etc). Also make sure to call this function only in the callback function, at the point where you say the object is properly populated.
Sidenote: I would prefer the following code just to make the template appear neater
res.render('review',{channel:mydata.channel,chanURL:mydata.chanURL,score:mydata.score,title:mydata.title,content:mydata.content});
and the template as
<ul>
<li>{{ channel }}</li>
<li>{{ chanURL }}</li>
<li>{{ score }}</li>
<li>{{ title }}</li>
<li>{{ content }}</li>
</ul>
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