Re: [nodejs] Getting multiple responses from express get (app.get)

224 views
Skip to first unread message

Ryan Schmidt

unread,
May 17, 2013, 6:07:00 PM5/17/13
to nod...@googlegroups.com
On May 17, 2013, at 07:45, Are wrote:

> I am currently using mongoose, node.js , express. I need to fill up multiple drop down menus from MongoDB.


> This calls the index (in app.js), which returns 1 collection.. but only the one:
> app.get('/', activityList.showActivities.bind(activityList));

This line doesn't *call* anything; it *defines* that *when* a user requests "/" from your server, the server will invoke a request handler function called activityList.showActivities.


> activitylist.js
> ActivityList.prototype = {
> showActivities: function(req, res) {
> point.find({}, function foundPoints(err, items) {
> res.render('index2',{title: 'CapCredits' , points: items})
> });
> },

When activityList.showActivities is invoked, it uses mongoose to find all data in the "point" collection, and when the results are received, calls res.render() to fill the indicated Jade template with the supplied variables and sends the resulting HTML to the browser.


> and in my index.jade:
>
> form(action="/asdad", method="post")
> select(name = "item[activity]")
> each activity in activities
> option(value='Test') #{activity.activityName}

The res.render() invocation above uses the template "index2" not "index". And here you're iterating over a variable called "activities", which your res.render() invocation did not supply; you supplied a variable called "points", so that's what you would be iterating over in the template.


> How can I do this for several collections? I have two collections which I want to fill two drop down menus with.

Instead of just calling find() on the point collection, you'll also call find on additional collections. Here's an example of finding all points and all balloons:

showActivities: function(req, res) {
point.find({}, function foundPoints(err, points) {
balloon.find({}, function foundBalloons(err, balloons) {
res.render('index2',{title: 'CapCredits' , points: points, balloons: balloons})
});
});
},

Note that this is *not* the best way to do it, because a) we find points, and then when that's done, we find balloons (in serial) whereas it would be more efficient to begin trying to find both points and balloons at the same time (in parallel); and b) the ever-increasing indentation is ugly and harder to follow. This is a common problem in nodejs for which there are an unlimited number of npm modules that can help you structure your code better. "async" is a very popular module for this.


> Is there any way I can use rest-calls like:
> app.get('/otherMenu', activityList.showActivities.bind(activityList));

That line would define that when a user requests "/otherMenu" from your server, the server would invoke the same activityList.showActivities function you've defined above. That's probably not useful.

I don't see how REST enters into what you're trying to do at all. The term "REST" is often used when talking about web services, but what you've described above is not a web service; it's a web server producing a normal HTML web site. Users will make one HTTP request to your server (for "/" for example) and will receive a formatted HTML response containing all sorts of information from various database collections that your server has assembled.

If you want a web service, and want, for example, that "/otherMenu" returns *just* the items of some database collection, perhaps in JSON format that you'll access via AJAX and turn into DOM elements on the fly in some client-side JavaScript, you can do that, but that's not what you were talking about above.

Alex Kocharin

unread,
May 18, 2013, 12:41:04 PM5/18/13
to nod...@googlegroups.com

> Note that this is *not* the best way to do it, because a) we find points, and then when that's done, we find balloons (in serial) whereas it would be more efficient to begin trying to find both points and balloons at the same time (in parallel);

If there's a lot of overhead involved (networking stuff), looking for them in parallel would be necessary.

But if we're looking for points and baloons in the same place (say, the same filesystem or database), they will be looked for in serial anyway, n'est-ce pas? You can't really turn a harddrive to a quantum superposition state so it would do two things at once. Therefore time to read would be the same, but async.js would really increase complexity here.

Ryan Schmidt

unread,
May 18, 2013, 5:34:09 PM5/18/13
to nod...@googlegroups.com

On May 18, 2013, at 11:41, Alex Kocharin wrote:

> But if we're looking for points and baloons in the same place (say, the same filesystem or database), they will be looked for in serial anyway, n'est-ce pas?

I don't know that. I don't know how database servers work internally. They might be multithreaded, and/or on a server with multiple CPU cores. The hard drives might be SSDs or a RAID. So they might be very able to handle multiple read requests in parallel.

The normal node way seems to be to start things in parallel, up to a point. I assume the database drivers will queue requests, if you ask for too many of them to be started at one time.

Peter Rust

unread,
May 20, 2013, 9:37:55 AM5/20/13
to nod...@googlegroups.com
With traditional platter (non-SSD) hard drives (and most DBs, which are reading from the disk if the data hasn't been cached to memory), it is most efficient to do multiple requests in parallel (rather than serial) because this allows the operating system to read the various bits of data from the disk in the optimal order using an elevator algorithm to minimize disk seeks (http://en.wikipedia.org/wiki/Elevator_algorithm).

Of course, there are limits to how many simultaneous files you can attempt to open -- if you're trying to open thousands of files, the https://github.com/isaacs/node-graceful-fs module can help manage things.
Reply all
Reply to author
Forward
0 new messages