2

I have a few route like this:

app.post('/user/me',        c.auth, c.striper.make,     c.user.edit,        c.user.requestDriver,       render);
app.post('/user/:id',       c.auth, c.targetUser,       c.user.makeDriver,  c.user.makeAdmin,           render);

When the validation fails, I want to skip all middlewear and go run the render-function, with req, res I can't use next(); for this because I don't know where in the order I am, is there some other way to call a specific function with the parameters res, req and next(); (my validation doesn't have access to those parameters so I can't just do

render(res, req, next)

Maybe some way to replace the middlewear setup in routes.

Himmators
  • 14,278
  • 36
  • 132
  • 223

3 Answers3

2

I suggest to call next(new Error(smth-data)); and render in Error-middleware with 4 params. Or you want special render for each route?

Aikon Mogwai
  • 4,954
  • 2
  • 18
  • 31
  • this sounds like what I'm looking for! Is this called something or are there any docs? What does new Error(smth-data) do? – Himmators Jul 16 '16 at 17:28
  • I'm not found more docs on Express-site, but it's standard method which not require any additional code: simple call next with Error and interrupt it in error-middleware (http://expressjs.com/en/guide/error-handling.html). – Aikon Mogwai Jul 16 '16 at 17:45
  • what does smth refer? – Himmators Jul 16 '16 at 18:22
  • You can put any string or json.stringified object. Also you can create separate Error-handlers for each route: handler must check error message and decide - proceed request or forwarding next. Error-middlewares makes chain similarly normal middlewares. – Aikon Mogwai Jul 16 '16 at 18:31
  • I had some more trouble: http://stackoverflow.com/questions/38415430/calling-next-inside-a-helper-function – Himmators Jul 16 '16 at 20:45
0

After digging out the stack overflow I found this post . It may give some hint to you.

Basically If you can make render to take 4 parameters like this

function (err, req, res, next) {}

then you may be able to jump there by passing error to next() like this

next({ type: 'database', error: 'datacenter blew up' });
Community
  • 1
  • 1
enRaiser
  • 2,606
  • 2
  • 21
  • 39
0

There are numerous ways to approach this. One way would be to use .bind() to pass the render function to each of your middleware functions. Then, when you decide you want to finish the request chain, you can just call render() and not call next().

app.post('/user/me', c.auth.bind(null, render), c.striper.make.bind(null, render),
    c.user.edit.bind(null, render), c.user.requestDriver.bind(null, render), render);

This will add a new argument for the render callback at the start of each of your middleware functions so you just add that to their declaration and then you have access to the desired render() function and can call it when needed.


Another way to do it is to create a new middleware that just adds the render function to the req object so it is then available to all the middleware so you can call it whenever you want.

app.post('/user/me',  setReqArg("renderFn", render), c.auth, c.striper.make, c.user.edit, c.user.requestDriver, render);

function setReqArg(propName, propValue) {
    return function(req, res, next) {
        req[propName] = propValue;
        next();
    }
}

After doing this, all middleware can get access to the render function at req.renderFn.

jfriend00
  • 683,504
  • 96
  • 985
  • 979