Reputation: 79
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?
Upvotes: 0
Views: 48
Reputation: 79
In the end of the day, i do something like:
function populateMiddlewares(req, res, next, middlewares) {
if (middlewares.length > 1) {
return middlewares.shift()(req, res, () => populateMiddlewares(req, res, next, middlewares));
}
return middlewares.shift()(req, res, next);
}
const ifType = (value, trueMiddlewares, falseMiddlewares) => (req, res, next) => {
if (req.query.type === value) {
return populateMiddlewares(req, res, next, [...trueMiddlewares]);
}
return populateMiddlewares(req, res, next, [...falseMiddlewares]);
};
app.get('/something', ifType('odd', [
odd1, odd2, odd3, odd4,
], [
even1, even2,
]), (req, res) => {
console.log('OK');
return res.send('OK');
});
So i can dynamically put it in my routes
Upvotes: 0
Reputation: 51
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
Upvotes: 1
Reputation: 203534
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.
Upvotes: 0
Reputation: 48314
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');
})
Upvotes: 0