Search code examples
node.jsexpresscontrollerexpress-4

Simple Error: Express 3 -> 4. Moving a controller and requesting index "Route.get() requires callback functions but got a [object Undefined]"


Hi I've seen similar errors, but none of them apply to this circumstance. I'm working through the Getting Mean book but applying all the lessons on Express 3 to an Express 4 app.

In app.js

app.set('views', path.join(__dirname, 'app_server/views'));
//index.jade is located here and confirmed to work before moving controller
...
require('./routes')(app); 
//Instead of app.use('/', routes);

In routes/index.js

var ctrl = require('../app_server/controllers/main');

module.exports = function (app) {
  app.get('/', ctrl.index);
}; 

In app_server/controllers/main.js

var express = require('express');
var router = express.Router();

router.get('/', function(req, res, next) {
  res.render('index', { title: 'Loc8r' });
});

// /* Also tried */
// exports.index = function(req, res){
//  res.render('index', { title: 'Express' });
// }; 

Running the app yields "Error: Route.get() requires callback functions but got a [object Undefined]" on the res.render('index', { title: 'Loc8r' }); line.

Been at this for hours. Help is much appreciated.


Solution

  • The error is likely caused by this line in route/index.js:

    app.get('/', ctrl.index);
    

    While app_server/controllers/main.js now makes use of express.Router, route/index.js hasn't been updated to match. It's still expecting a ctrl.index, which is no longer being defined.

    console.log(ctrl);       // {}
    console.log(ctrl.index); // undefined
    

    app_server/controllers/main.js should export the Router it's defining:

    var express = require('express');
    var router = module.exports = express.Router();
    //           ^^^^^^^^^^^^^^
    
    // ...
    

    So it can be used as middleware in routes/index.js:

    module.exports = function (app) {
      app.use(require('../app_server/controllers/main'));
    };
    

    [Edit] Regarding my comment below:

    /** app_server/controllers/main.js **/
    var express = require('express');
    var router = module.exports = express.Router();
    
    // ...
    
    /** routes/index.js **/
    var express = require('express');
    var router = module.exports = express.Router();
    
    router.use(require('../app_server/controllers/main.js'));
    // ...
    // router.use('/area1', require('../app_server/controllers/area1.js'));
    // router.use('/area2', require('../app_server/controllers/area2.js'));
    
    /** app.js **/
    // ...
    
    app.use(require('./routes'));