0

In NodeJS coupled with Mongoose. How do I render multiple collections at once to a view?

I know I could do something like this:

Page.find().sort({ 'order': 1 }).exec(function(err, pages) {
    Portfolio.find().sort({ 'order': 1 }).exec(function(err, portfolios) {
        res.render('layout', {
            title: 'Index',
            pages: pages,
            portfolio: portfolios
        });

        ...

But that would also make my render pretty steep if I had more than two collections I would render. Is there any other way I can do this?

Eventually store the Page.find() and Portolio.find() before i parse it to my render?

Thanks in advance

aventic
  • 1,494
  • 2
  • 16
  • 23

1 Answers1

0

(Beforehand: I found myself lost writing a long, very looooong answer to this question and decided to rewrite it later again as a blog post. I try to summarize the essentials here.)

That's a problem many people are facing when dealing with asynchronous event-driven programming and coming from a more synchronous and imperative background. It's also known as the "callback hell".

There is no short answer indeed because to get the big picture we should have a closer look on what is going to be achieved, what techniques and patterns are involved and what this means for programming for asynchronous execution environments like nodeJS is.

I'll try to break it down in some questions:

Q: Depend Portfolios in some way on Pages?

If yes, wouldn't it be nice to model that in a NoSQL database that's well suited for flexible or loose dependencies - like MongoDB is? Your data would then probably be accessible through one resulting collection.

Q: Is it really necessary to choose the classic "bloated" view approach? Is there any chance of separating the request to Portfoliosfrom that to Pages?

If yes, split up your routes and choose an ajaxified delivery of partial views! (even better and cleaner of course would be if you just send JSON data over the wire and do rendering client side... but, okay, I'll stop here.)

Q: Are my first two questions superfluous because you need that independent data portions exactly the way like shown in your code snippet? Is this definitely a top level composition of data portions to be delivered simply as a rendered view in one response?

If yes, switch to even-driven thinking and try to express the data composition with "dependency chains" utilizing e.g. a library implementing the Promises. This might help you to keep the advantages of asynchronous processing while gathering results mandatory for subsequent actions. Also have a look on this stackoverflow question.

I'll post another comment right here as soon as my blog entry arrives. Nevertheless: I hope that my answer helps you a bit helping yourself!

Community
  • 1
  • 1
matthias
  • 2,255
  • 1
  • 23
  • 28