Home > Enterprise >  Express define next middlewares on req condition
Express define next middlewares on req condition

Time:08-12

Let's say i have something like:

function odd1(req, res, next) {
    console.log('odd1');
    return next();
}
function odd2(req, res, next) {
    console.log('odd2');
    return next();
}
function even1(req, res, next) {
    console.log('even1');
    return next();
}
function even2(req, res, next) {
    console.log('even2');
    return next();
}

app.get('/something', (req, res, next) => {
    if (req.query.type === 'odd') {
        // return odd1, odd2, next
    }
    // return even1, even2, next
}, (req, res) => {
    console.log('OK');
    return res.send('OK');
});

I want to define the next middlewares on a queryparam condition; if the type is 'odd' then continue to odd1, odd2, then send 'OK'; otherwise it goes to even1, even2, then send 'OK'

I've tried something like:

app.get('/something', (req, res, next) => {
    if (req.body.type === 'odd') {
        return odd1(req, res, odd2(req, res, next));
    }
    return even1(req, res, even2(req, res, next));
}, (req, res) => {
    console.log('OK');
    return res.send('OK');
});

But it doesn't work properly

odd2
OK
odd1
TypeError: next is not a function

Is this idea possible to do?

CodePudding user response:

I'd be explicit - there's a first middleware that sets the type and all other middlewares check this type

function checktype(req, res, next) {
    if ( req.query.type == 'odd' ) {
        req.reqtype = 'odd';
    } else {
        req.reqtype = 'even';
    }
    next();
}

function odd1(req, res, next) {
    if ( req.reqtype == 'odd' )
        console.log('odd1');
    return next();
}
function odd2(req, res, next) {
    if ( req.reqtype == 'odd' )
        console.log('odd2');
    return next();
}
function even1(req, res, next) {
    if ( req.reqtype == 'even' )
        console.log('even1');
    return next();
}
function even2(req, res, next) {
    if ( req.reqtype == 'even' )
        console.log('even2');
    return next();
}

app.get('/', checktype, odd1, odd2, even1, even2, (req, res) => {
    res.end('ok');
})

CodePudding user response:

Here's a possible solution:

function checkType(type) {
  return (req, res, next) => {
    if (req.query.type === type) {
      return next();
    }
    return next('route');
  };
}

app.get('/', checkType('odd'),  odd1, odd2, odd3);
app.get('/', checkType('even'), even1, even2);

This uses next('route') in a middleware chain to skip all the remaining middleware (to the next route middleware) if the type provided doesn't match the proper type for the chain.

So if req.query.type equals odd, it will run the odd1/odd2/odd3 middleware functions. If it's not odd, then it will skip to the next route middleware, which also happens to match the same path, and check if type is even.

However, with this setup you cannot add odd/even middleware functions dynamically, you need to declare them upfront.

CodePudding user response:

Here is one line solution :-

Just Replace the third argument when calling odd1 function with the function that return odd2 for your next argument.

Inside the if statement, when type is odd :-

...
if ( req.query.type == 'odd') {
  return odd1(req, res, () => odd2(req, res, next));
}
...

In this way, you will get the right order i.e.,

odd1
odd2
OK

The main bug is that you make mistake in 3rd argument when calling odd1 beacuse it should be a function, but you passed a expression i.e., odd2() which return next(), which is also a expression because it has a () sign, which returns the third argument of app.get() and it returns null.

It means you returned null as the third argument for odd1 inside the if block when type is odd

  • Related