4

I am currently working on formBuilder (client javascript <=> JSON <=> node), so i need effective way to handle JSON data on server. All forms are bind on one route, catched by middleware, so i need something like this:

Code is simplified (no regexs, req validators etc ..)

var middleware = require('../middleware'); // simple dir to object export

exports = module.exports =function(req,res,next) {
  if(req.xhr && req.is('application/json')) {
    var i, items = req.body.events.length;
    for(i = 0; i < items; i++) {
      var event = req.body.events[i];
      if(middleware.forms[event] {
        // -----------------
        and here add that middleware into current flow ..
        // -----------------
      }
    }
  } else {
    return next();
}

Easiest way is to prepare list of middleware, which will be used and call them in final route witch async .. but that i donw regard this as good way ..

So, i there any way to add requested middlwares to current flow, but before filan route ?

2 Answers2

12

Middleware are just functions. So there is nothing wrong with just calling them. I had the same problem last week and I wrote a little helper.

 var walkSubstack = function (stack, req, res, next) {

  if (typeof stack === 'function') {
    stack = [stack];
  }

  var walkStack = function (i, err) {

    if (err) {
      return next(err);
    }

    if (i >= stack.length) {
      return next();
    }

    stack[i](req, res, walkStack.bind(null, i + 1));

  };

  walkStack(0);

};

You can use it with an array or just one function.

walkSubstack(middleware, req, res, next);
//or
walkSubstack([middleware, middleware], req, res, next);
Piotr Tomasik
  • 9,074
  • 4
  • 44
  • 57
Pickels
  • 33,902
  • 26
  • 118
  • 178
  • As i said: "Easiest way is to prepare list of middleware, which will be used and call them in final route witch async .. but that i donw regard this as good way .." I dont now how many of them will be used ... so i cant simple call it .. – Michal Taneček Jul 30 '12 at 10:54
  • 1
    btw the second function parameters has a small typo res should be req – Piotr Tomasik Mar 24 '13 at 08:06
  • 1
    the other one bro :) walkSubstack([middleware, middleware], res, req, next); should be walkSubstack([middleware, middleware], req, res, next); – Piotr Tomasik Mar 25 '13 at 22:33
  • @Piotr you keep catching them. – Pickels Mar 26 '13 at 18:10
  • I have turned this into a module here, if anyone's interested: https://github.com/Xananax/connect-url-pipe – Xananax Nov 19 '14 at 13:27
0

I wrote something very similar:

let isActive1 = false;
let isActive2 = false;
let func1MD = (req, res, next) { /* ... */ }
let func2MD = (req, res, next) { /* ... */ }

let middleware = (function () {

  // middleware #1
  function func1(req, res, next) {
    if (!isActive1) { return next(); }

    return func1MD.call(null, req, res, next);
  }

  // middleware #2
  function func2(req, res, next) {
    if (!isActive2) { return next(); }

    return func2MD.call(null, req, res, next);
  }

  // Returning an array of all middlewares to be called sequentially
  return [
    func1,
    func2
  ]
})();

app.use(middleware);
Mor Shemesh
  • 2,689
  • 1
  • 24
  • 36