0

Im currently very new to Node.js - Express framework and Im trying to emulate a MVC pattern, so far I got this

app.js

var express = require('express');
var path = require('path');
var favicon = require('static-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var http = require('http');

var app = module.exports = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.set('port', process.env.PORT || 3000);

app.use(favicon());
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

require('./routes');

/// catch 404 and forwarding to error handler
app.use(function(req, res, next) {
    var err = new Error('Not Found');
    err.status = 404;
    next(err);
});

/// error handlers

// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
    app.use(function(err, req, res, next) {
        res.status(err.status || 500);
        res.render('error', {
            message: err.message,
            error: err
        });
    });
}

// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
    res.status(err.status || 500);
    res.render('error', {
        message: err.message,
        error: {}
    });
});

http.createServer(app).listen(app.get('port'), function() {
    console.log("Running server");
});

Just a normal app.js generated with the express generator with some modifications, now my routes/index.js

app = require('../app');

app.get('/test', function(req, res) {
    require('./controllers/test.js');
    test();
}); 

app.get('/', function(req, res) {
    res.send('yankevf');
}); 

As you can see on route /test if looks for module /controllers/test.js but since theres no actual module it wont work..

How can I include a file that is inside the folder controllers? since my server keeps searching inside node_modules

7
  • 1
    No idea what you are asking Commented May 7, 2014 at 19:39
  • 1
    "I'm trying to enumate a MVC pattern" - god, why? Commented May 7, 2014 at 19:39
  • My exact feeling...@Dalorzo Commented May 7, 2014 at 19:39
  • Well, came from using PHP and a MVC pattern really helps, how should I work with node - express then? everything inside the route?. How can I include a file that is inside the folder controllers? since my server keeps searching inside node_modules Commented May 7, 2014 at 19:40
  • I have no idea what you did in PHP, but it was not the MVC pattern. MVC requires views to observe models and over a stateless protocol that's pretty much impossible unless you polled with AJAX all the time (or used websockets all the time). Commented May 7, 2014 at 19:42

1 Answer 1

3

It looks like you're basically there...

From your question it sounds like your folder structure is:

./app.js
./routes
  -> index.js
./controllers
  -> test.js

If that's the case, this should work:

app = require('../app');

app.get('/test', function(req, res, next) {
    test = require('../controllers/test.js'); // Note the path, one directory up
    // Passing the req, res, next arguments on to your controller allows it to respond
    // i.e. res.json({msg: 'hello world'}).
    test(req, res, next);
});

Although you probably don't want to load your controller on every new request, but rather load (require) it once, and call it on every request:

app = require('../app');
testController = require('../controllers/test.js');

app.get('/test', function(req, res, next) {
    // Passing the req, res, next arguments on to your controller allows it to respond
    // i.e. res.json({msg: 'hello world'}).
    testController(req, res, next);
});

If you're directly passing these arguments to your controller (like you should), you can write it more succinctly:

app = require('../app');
testController = require('../controllers/test.js');

// Call your controller, automatically passing 'req', 'res', 'next' arguments. 
app.get('/test', testController);

For a full example which automates the mounting of routes, checkout: Express MVC example

Sign up to request clarification or add additional context in comments.

2 Comments

How can I send the res and req objects to the controller? so I can use res.send on the controller .js
I've edited the answer to try to clarify. There are also great example applications in the express repository on github. Some are written to show how to use express in an MVC style backend.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.