Lurk21
Lurk21

Reputation: 2337

expressjs - unable to process request

I am learning nodejs / expressjs and shoehorning it into the Spring MVC pattern because I figure I can keep my file's cohesive. But it's not quite working out as I would expect...

server.js

const express = require('express');
const bodyParser= require('body-parser');
const MongoClient = require('mongodb').MongoClient;
const app = express();

var PeopleController = require('./controller/PeopleController.js')
var db;

app.all('/*', function(req, res, next) {
  var path = req.url;
  var controller;

  switch (true) {
    case /\/people.*/g.test(path):
      controller = new PeopleController();
      console.log("people");
      controller.process(req, res, next);
      break;
    case /\/foo.*/g.test(path):
      console.log("foo");
      break
    default:
      console.log("nada");
      break;
  }
});

PeopleController.js

const express = require('express');
const bodyParser= require('body-parser');
const MongoClient = require('mongodb').MongoClient;
const app = express();

var PeopleController = function PeopleController() {}

PeopleController.prototype.process = function (req, res, next) {
  var baseURL = '/people';

  console.log('path is ' + req.path);

  app.use(bodyParser.urlencoded({extended: true}));
  app.set('view engine', 'ejs');

  app.get(baseURL, (req, res) => {
    console.log('people get');
  });

  app.post(baseURL, (req, res) => {
    console.log('people post');
  });
};

module.exports = PeopleController;

Then when I do a GET on /people/ I get the following console out...

people
path is /people/

I expect the app.get to run and to get the following output:

people
path is /people/
people get

Upvotes: 1

Views: 292

Answers (2)

Kunal
Kunal

Reputation: 1256

Lurk I'd highly recommend using express.router like so:

PeopleController.js

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

// then apply middleware
router.use(...);

// then define your endpoints
router.get('/', (req, res) => {
  console.log('get PeopleController.js root');
}

module.exports = router;

In server.js

...
const PeopleController = require('./controller/PeopleController.js');

// apply PeopleController to '/people' route
app.use('/people', PeopleController);

So now when you request GET /people you should see the console.log on node. The big benefit of this approach is it keeps your code clean (no switching based on route, you let express handle restful actions)

Upvotes: 1

Artur
Artur

Reputation: 357

This is happening because you have only one instance of Express listening on port.

In server.js:

const express = require('express');
const bodyParser= require('body-parser');
const MongoClient = require('mongodb').MongoClient;
const app = express(); // we create an instance of Express
...
app.listen(process.ENV.PORT); //this specific instance listening on port

When you creating new instance of PeopleController you must past an app in server.js

const app = express();
...
controller = new PeopleController(app);

And import in PeopleController.js

const express = require('express'); // delete this
const app = express(); // delete this

//add this:
var PeopleController = function PeopleController(appInstance) {
  this.app = appInstance;
}

PeopleController.prototype.process = function (req, res, next) {
  var baseURL = '/people';
  var app = this.app;

  console.log('path is ' + req.path);

  app.use(bodyParser.urlencoded({extended: true}));
  app.set('view engine', 'ejs');

  app.get(baseURL, (req, res) => {
    console.log('people get');
  });

  app.post(baseURL, (req, res) => {
    console.log('people post');
  });
};

Upvotes: 2

Related Questions