2

I have an issue when requiring Express.js middleware; I have the code in app.'s:

...
var middlewares = require('./middlewares');
...
routes = require('./routes')(app, config, crypto, middlewares, models, oauth2);
...

This requires ./middlewares/index.js:

/*jslint es5: true, indent: 2, node:true, nomen: true, maxlen: 80, vars: true*/

'use strict';

var middlewares = function (app, config, models, oauth2) {
  var that = {};

  that.touch = require('./touch.js')(app, config, models, oauth2);

  return that;
};

module.exports = middlewares;

Which in turn (the above is simplified but would contain require other middleware too) requires ./middlewares/touch.js:

/*jslint es5: true, indent: 2, node: true, nomen: true, maxlen: 80, vars: true*/

'use strict';

var touch = function (app, config, models, oauth2) {
  return function (req, res, next) {
    console.log('Touch');

    next();
  };
};

module.exports = touch;

And call it from ./routes/index.js:

/*jslint es5: true, indent: 2, node:true, nomen: true, maxlen: 80, vars: true*/

'use strict';

var routes = function (app, config, crypto, middlewares, models, oauth2) {
  var that = {};

  app.get(
    '/',
    middlewares.touch(app, config, models, oauth2),
    function (req, res) {
      res.send('Hello world!');
    }
  );

  that.auth = require('./auth')(app, config, crypto, models, oauth2);

  return that;
};

module.exports = routes;

Though when I do this I get the error:

TypeError: Object function (app, config, models, oauth2) {
  var that = {};

  that.touch = require('./touch.js')(app, config, models, oauth2);

  return that;
} has no method 'touch'

When I require ./middlewares/touch.js from app.js like:

...
var touch = require('./middlewares/touch.js');
...
routes = require('./routes')(app, config, crypto, touch, models, oauth2);
...

And in ./routes/index.js I call it like:

/*jslint es5: true, indent: 2, node:true, nomen: true, maxlen: 80, vars: true*/

'use strict';

var routes = function (app, config, crypto, touch, models, oauth2) {
  var that = {};

  app.get(
    '/',
    touch(app, config, models, oauth2),
    function (req, res) {
      res.send('Hello world!');
    }
  );

  that.auth = require('./auth')(app, config, crypto, models, oauth2);

  return that;
};

module.exports = routes;

I am error free! Must be the way I am referencing it through ./middlewares/index.js but I can for the life of me work it out?

Any ideas Stack Overflow?

EDIT:

OK, so then the question remains;

  • I want to require ./middlewares/index.js from inside app.js
  • ./middlewares/index.js requires all my middlewares e.g. ./touch.js
  • I only need to pass the middlewares object into other modules to access its methods e.g. middlewares can be passed into my routes module and I can reference the touch middleware like middlewares.touch()

Very simply; I wish to require all my middlewares and pass them into the routes module like:

...
var middlewares = require('./middlewares');
...
routes = require('./routes')(app, middlewares);
...

And use my middlewares in a route like:

/*jslint es5: true, indent: 2, node:true, nomen: true, maxlen: 80, vars: true*/

'use strict';

var routes = function (app, middlewares) {
  var that = {};

  app.get(
    '/',
    middlewares.touch,
    function (req, res) {
      res.send('Hello world!');
    }
  );

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

  return that;
};

module.exports = routes;

How should I go about that? Look at the top of this question to see how I'm trying (and failing) to do it now, thanks everyone for their help!

In addition, should modules return something, e.g.; the routes module doesn't really need to return anything, or does/should it?

3 Answers 3

2

Frist off: both awnsers are correct

the middlewares/index.js returns a function in its exports

and inside the routes.js you try to use the member touch of that function, which doenst exist

Secondly:

It looks like you could us some help structuring your app, which youve done very thoroughly but doing it this way makes the components very dependant on eachother/the app

you inject the dependancies (app, config, crypto, middlewares, models, oauth2, ... etc) into each module instead of having them get their own

in your app.js you probably do something like

var OAuth2Lib = require('some/path/oauth2');
var oauth2 = new OAuth2Lib(some.config);

and repeat for all other [crypto, cnfig, models,...] once thats done you run the

routes = require('./routes')(app, config, crypto, middlewares, models, oauth2);

If you put the construction code to make the oahth2 into a new module you can require that whenever you need it (put it in lib/oauth2.js):

var OAuth2Lib = require('some/path/oauth2');
var oauth2 = new OAuth2Lib(some.config);
module.exports = oauth2;

to use that inside: ./middlewares/touch.js:

var oauth2 = require('../lib/oauth2');
var config = require('../config/config');
var models = require('../lib/models');

var touch = function (app) {
  return function (req, res, next) {
    console.log('Touch');

    next();
  };
};

module.exports = touch;

now there is only the app dependancy left (if you need that at all) be carefull with middleware order, especially things like cookieParse, bodyParser (express) should be app.use'd before your own custom middlewares

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

Comments

1
+50

The issue is that middlewares returns a function that when executed returns an object instead of just an object like you are using it in ./routes/index.js.

You can do 1 of 2 things.

1) Change ./middlewares/index.js to set module.exports to an object literal.

/*jslint es5: true, indent: 2, node:true, nomen: true, maxlen: 80, vars: true*/

'use strict';

var middlewares = {

  touch : require('./touch.js')(app, config, models, oauth2)

};

module.exports = middlewares;

-- OR --

2) Change ./routes/index.js to run middlewares before calling touch.

/*jslint es5: true, indent: 2, node:true, nomen: true, maxlen: 80, vars: true*/

'use strict';

var routes = function (app, config, crypto, middlewares, models, oauth2) {
  var that = {};

  app.get(
    '/',
    middlewares().touch(app, config, models, oauth2),
    function (req, res) {
      res.send('Hello world!');
    }
  );

  that.auth = require('./auth')(app, config, crypto, models, oauth2);

  return that;
};

module.exports = routes;

I am partial to option 1 but it depends on if you need to do something in ./middlewares/index.js before building up the return object.

Based on the code you have it looks like option 1 suits your needs.

Comments

1

Every function is an object.

Functional object middlewares has no method touch, and this is true. I am not sure what you are trying to achieve with this code, but touch method is in what the function returns, and not a member of the function itself.

This would work, in terms of syntax: middlwares().touch, or direct member assignment middlwares.touch = ..., and then you can access it, although I highly doubt if this is what you had in mind.

2 Comments

Yes; but the function returned by ./middlewares/touch.js is assigned to middlewares.touch in the first examples, is it not? Albeit though ./middlewares/index.jsthough I would prefer it that way, as I would like all middlewares avaliable from one object e.g. middlewares.touch, middlewares.otherFuncetc. I think it must be something to do with the ./middlewares/index.js proxy?
Thanks, I've added to my question then; could you take a look and suggest how I should be doing this then, I obviously don't understand your first answer unfortunately. Could you make it more comprehensive? Thanks for your help so far!

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.