giray acar giray acar - 1 month ago 14
Node.js Question

Express Router.use in middleware

I'm new to Express.

I am trying to route a request according to a value in DB. To do this I am calling a service function.
Routing is working successfully but I am loosing the request object.
I have tried to pass the req to the service but it didn't work.

Any help showing how to do this would be nice.

Here is my code block.

var companyService = require("services/companyService");
router.use('/', function (req, res, next) {
companyService.isCompanyOnline(req.body.companyCode).then(function (company) {
if (company) {
router.use('/', require("api/controllers/online"));
}
else {
router.use('/', require("api/controllers/offline"));
}
});
next();
});

module.exports = router;


Services.companyService:

function isCompanyOnline(code) {
var deferred = Q.defer();
companies.findOne({ companyCode: code }, function (err, company) {
if (err) deferred.reject(err.name + ': ' + err.message);
//if (err) throw err;
if (company) {
// return company online parameter
deferred.resolve(company.isOnline);
} else {
// company not found
deferred.resolve();
}
});
return deferred.promise;
}

Answer

You are losing the request object because you are not passing it anywhere.

I believe your main issue here is the fact that you have three route handlers registering on the same path /. If I am not mistaken they will be all called in-order that you add them. But the order in your depends on the if you are placing the router.use() calls. So it's unpredictable, and likely not going to work as you expect. Once they are registered they stay in the middleware stack until you restart the app.

I suggest you refactor to have the online/offline logic in one place, or register all your middlewares at once, so you know in which order they get called, and use next() accordingly.

On another note, if you want to pass an argument to required modules, do this:

Change api/controllers/online and the other, to accept an argument, and return the handler function that you are passing.

// your code in api/controllers/online and offline

module.exports = function (req) {
    // now you have req available in-scope here
    function yourFunctionThatNeedsReq (req) {
        // do stuff with req
    }
    return yourFunctionThatNeedsReq;
};

Then update your require like so. Note the …(req).

router.use('/', require("api/controllers/online")(req) );