0

I've been following some nodejs - mongodb - express tutorials. I understand some of the basics such as the

  • the general principal of using app.js as a main (for want of a better term) controller for the site.
  • Storing all third party modules in their own node_modules directory.

  • Placing html/template engine files in views

  • Using the public directory as you might the skin folder in a php project

I'm trying to combine some of the things that I've come across in a lot of the tutorials and the one thing that is troubling me is how condensed the app.js folder is becoming. This breaking-up-the-app question is very similar to mine but I'm looking for a less subjective reply I think. The accepted answer suggests a method that he uses

~/app
|~controllers
| |-monkey.js
| |-zoo.js
|~models
| |-monkey.js
| |-zoo.js
|~views
| |~zoos
|   |-new.jade
|   |-_form.jade
|~test
|  |~controllers
|    |-zoo.js
|  |~models
|    |-zoo.js
|-index.js

I like how this looks and would like to implement something similar on my project.

For Example

I'm using the active-menu module and it seems to take up a lot of space in my app.js

//menu
var activeMenu = require('active-menu');
// Create a New Instance
var adminMenu = new activeMenu('adminMenu');
// Set HTML Attributes for the Top <ul> element
adminMenu.setAttributes({class : 'menu', id : 'admin-menu'});
// Home Node
var homeNode = adminMenu.addMenuNode('Home', '/');
homeNode.setAttributes({class : 'home home-icon', id : 'home-link'});

var postsNode = adminMenu.addMenuNode('About', '/about');
postsNode.setAttributes({class : 'about about-icon'});

var newPostNode = postsNode.addMenuNode('Contact', '/contact');
newPostNode.setAttributes({class : 'contact-post contact-icon'});

var app = express();

// Use Menu
app.use(adminMenu.menu); 

I followed this tutorial to achieve that. It works so the tutorial served it's purpose but it would be better if inside my controller directory I could get the links dynamically somehow and just reference app.use(adminMenu.menu); so that it could be called in the layout.jade so how can I write this?

The same seems be the case for the app.get/put/post/delete etc. Based on this tutorial I came to have this also in my app.js file.

app.get('/:collection', function(req, res) { 
var params = req.params; 
collectionDriver.findAll(req.params.collection, function(error, objs) { 
      if (error) { res.send(400, error); } 
      else { 
          if (req.accepts('html')) {
              res.render('data',{objects: objs, collection: req.params.collection}); 
          } else {
              res.set('Content-Type','application/json'); //G
              res.send(200, objs); //H
          }
       }
    });
});

app.get('/:collection/:entity', function(req, res) { //I
    var params = req.params;
    var entity = params.entity;
    var collection = params.collection;
    if (entity) {
        collectionDriver.get(collection, entity, function(error, objs) { 
            if (error) { res.send(400, error); }
            else { res.send(200, objs); } //K
        });
    } else {
        res.send(400, {error: 'bad url', url: req.url});
    }
});

app.post('/:collection', function(req, res) {
    var object = req.body;
    var collection = req.params.collection;
    collectionDriver.save(collection, object, function(err,docs) {
        if (err) { res.send(400, err); } 
        else { res.send(201, docs); } //B
    });
 });

app.put('/:collection/:entity', function(req, res) { //A
    var params = req.params;
    var entity = params.entity;
    var collection = params.collection;
    if (entity) {
        collectionDriver.update(collection, req.body, entity, function(error, objs) { //B
            if (error) { res.send(400, error); }
            else { res.send(200, objs); } //C
         });
    } else {
        var error = { "message" : "Cannot PUT a whole collection" };
        res.send(400, error);
    }
});

app.delete('/:collection/:entity', function(req, res) { //A
    var params = req.params;
    var entity = params.entity;
    var collection = params.collection;
    if (entity) {
        collectionDriver.delete(collection, entity, function(error, objs) { 
           if (error) { res.send(400, error); }
           else { res.send(200, objs); } 
        });
   } else {
       var error = { "message" : "Cannot DELETE a whole collection" };
       res.send(400, error);
   }
});

Again how can I write this so that these calls are in a model/controller and only seen by app.js when needed?

One objective that I am hoping to achieve through this question is an understanding of how to do this WITHOUT an additional framework.

Some reading that I did along my way before writing this question - Node Beginner - Nodejs with express, jade and stylus - Mongodb

Community
  • 1
  • 1
develophper
  • 302
  • 1
  • 3
  • 18
  • Sails.js? (http://sailsjs.org) – David Sherret Feb 24 '15 at 22:12
  • Sooner or later after following the current trend in web development you are going to switch to frontend either Angularjs, Bakbone or Ember.js to manage your front end routing, view logic. I suggest rather than sticking to views on node.js you can actually leverage the power of Angularjs on your app. So basically then express will act as REST Api engine and angular will do the job for you to fetch data from express endpoints and display. In that way you will be having clean and scalable architecture. Let me know if you need any help on this. – NarendraSoni Feb 25 '15 at 01:23
  • if you want to use the MVC pattern without using ``express``, you may look at https://github.com/piyasde/minimalweb , there you have a pattern which comes near to your approach... – Piyas De Feb 25 '15 at 01:36

2 Answers2

1

Even though the question was really aimed at finding a solution other than using an additional framework I've come to the conclusion that this is not feasible.

I've decided to just go with angular.js and I couldn't recommend more this 3 part tutorial more.

develophper
  • 302
  • 1
  • 3
  • 18
0

Here is my current approach: https://github.com/tkiddle/expressPlate/tree/tkiddle

It's a work in progress, but does work quite well.

tkiddle
  • 480
  • 1
  • 3
  • 12