Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

No HTML output using Express to output MongoDB results

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 ?

like image 226
devolved Avatar asked Mar 04 '23 08:03

devolved


1 Answers

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>

like image 105
Madhav Sarpal Avatar answered Mar 15 '23 01:03

Madhav Sarpal