[SOLVED] Array of functions with additional arguments in the express router middleware

Issue

const cb0 = function (data, req, res, next) {
  console.log('CB0')
  next()
}

const cb1 = function (data, req, res, next) {
  console.log('CB1')
  next()
}

app.get('/example/d', [cb0, cb1], (req, res, next) => {
  console.log('the response will be sent by the next function ...')
  next()
}, (req, res) => {
  res.send('Hello from D!')
})

From the above code, I’m passing an array of functions [cb0, cb1] and each function requires some data attribute of type any and additional parameters like req, res and next.

Earlier,I tried passing the data attribute like below format using bind concept.
app.get('/example/d', [cb0.bind(data), cb1.bind(data)], (req, res, next)

But if I use the bind concept, then how to pass the other required attributes (req, res and next)?
Is there any other way to pass all the parameters, including data without bind? or do we have any limitations in using the array of functions in the express?

Solution

First, you’ve used bind incorrectly (for how your functions are written): The first argument to bind is the value to use as this when calling the function; it’s only the subsequent arguments that define arguments to give the function when called. So you’d want cb0.bind(null, data) rather than cb0.bind(data).

But if I use the bind concept, then how to pass the other required attributes (req, res and next)?

(They’re arguments, not attributes.) Express does that when it calls your function. The arguments will follow the arguments you’ve "baked into" your functions via bind. Your functions are already set up correctly to handle that order (data, req, res, next), so with the change, you should be good to go.

So:

app.get('/example/d', [cb0.bind(null, data), cb1.bind(null, data)], (req, res, next) => {
    // ...

Just for clarity, here’s an example of a function with data bound to it via bind being called with further arguments:

function example(data, other) {
    console.log(`data = ${JSON.stringify(data)}, other = ${JSON.stringify(other)}`);
}

const ex = example.bind(null, "baked in arg");

// Emulating Express calling the middleware:
ex("passed arg");

Side note: You don’t have to put your middleware functions in an array, express is happy with them as discrete arguments instead:

app.get('/example/d', cb0.bind(null, data), cb1.bind(null, data), (req, res, next) => {
    // ...

Either way is fine.

Answered By – T.J. Crowder

Answer Checked By – Clifford M. (BugsFixing Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *