1

I am using MongoJS to fetch data from mongo db in the following way: app.js:

var db = mongojs('db', ['events']);

And then:

   app.get('/', function(req, res){
    db.events.find(function(err,docs){
        res.render('index', {
        title: 'Events',
        events: docs
    });
    })  
});

This method works, I then fetch it using ejs as the view engine the following way: index.ejs:

<% events.forEach(function(event){ %>

<a><%= event.event_name %></a></br>
<a><%= event.event_description %></a> 

<% }) %>

This all works, however, How could I grab data from a different collection in the same ejs page? I've been trying to do it the following way: app.js: edited into

var db = mongojs('db', ['events', 'groups']);

And then:

app.get('/', function(req, res){
        db.events.find(function(err,docs){
            res.render('index', {
            title: 'Events',
            events: docs
        });
        })  
    });


       app.get('/', function(req, res){
        db.groups.find(function(err,docs){
            res.render('index', {
            title: 'Groups',
            groups: docs
        });
        })  
    });

Followed by the EJS:

<% groups.forEach(function(group){ %>

            <p><a><%= group.group_name %></a></br>
            <a><%= group.editor %></a></p>
            <a><%= group.members %></a></p>

 <% }) %>

The error that I'm getting is that 'groups' is not defined, however if I flip them like this inn app.js:

app.get('/', function(req, res){
            db.groups.find(function(err,docs){
                res.render('index', {
                title: 'Groups',
                groups: docs
            });
            })  
        });

app.get('/', function(req, res){
            db.events.find(function(err,docs){
                res.render('index', {
                title: 'Events',
                events: docs
            });
            })  
        });

Then it says events is not defined. How do I declare them both in one without one overwritting the other? If you can help with this, thank you so much.

Bharathvaj Ganesan
  • 3,054
  • 1
  • 18
  • 32
MrG
  • 33
  • 9

2 Answers2

0

You can only have one root app.get('/'... call. Try combining your routes like this:

app.get('/', function(req, res) {
    db.groups.find(function(groupsErr, groupDocs){

        // now get events
        db.events.find(function(eventsErr, eventDocs){
            res.render('index', {
                title: 'Events',
                events: eventDocs,
                groups: groupDocs
            });
        });
    });
});

You can also handle this in a slightly prettier fashion (less nested) using promises.

app.get('/', function(req, res) {
    let groupsPromise = new Promise((res, rej) => {
        db.groups.find((err, docs) => {
            if (!err) res(docs);
            else rej(err);
        });
    });

    let eventsPromise = new Promise((res, rej) => {
        db.events.find((err, docs) => {
            if (!err) res(docs);
            else rej(err);
        });
    });

    Promise.all([groupsPromise, eventsPromise])
    .then(docArr => {
        let groupDocs = docArr[0];
        let eventDocs = docArr[1];

        res.render('index', {
            title: 'Events',
            groups: groupDocs,
            events: eventDocs
        });
    })
    .catch(console.error);
});
Blundering Philosopher
  • 6,245
  • 2
  • 43
  • 59
0

After the first handler gets executed, the second one does not, so the simplest way is to chain your queries as:

let events;
app.get('/', function(req, res) {
db.events.find(function(err, docs) {
  events = docs;
  db.groups.find(function(err, docs) {
    res.render('index', {
      title: 'Items',
      groups: docs,
      events: events
    });
  })
});
})

The code above, couls be improved with the use of promises or async/await. I recommend you search about asynchronous functions for better programming in Javascript

Osvaldo Maria
  • 340
  • 5
  • 14
  • I'm glad to know @MrG .. If the answer was helpful/ solved the issue, It is good and encouraging practise to upvote or set it as the correct answer, so that others know it worked for your case – Osvaldo Maria Feb 28 '18 at 20:48
  • I did so, but as I have less than 15 reputation it does not register – MrG Mar 04 '18 at 23:50