Domanda

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?

È stato utile?

Soluzione 2

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.

Altri suggerimenti

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

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top