Express: passing middleware as an array does not work

Created on 23 Mar 2014  路  16Comments  路  Source: expressjs/express

var middleware = [loadForum, loadThread];

app.get('/forum/:fid/thread/:tid', middleware, function(){
  // ...
})

the above part gives me the following error:

Error: Route.use() requires callback functions but got a [object Array]

It works fine if i pass the middleware like this:

app.get('/forum/:fid/thread/:tid', loadForum, loadThread, function(){
  // ...
})

According to the 4.x docs, the array should be flattened by express, but it doesn't seem to work as intended

Most helpful comment

@php-workx @agauniyal an array of middleware is still supported:

var express = require('express')
var app = express()

var apple = function (req, res, next) {
  console.log('apple')
  next()
}

var book = function (req, res, next) {
  console.log('book')
  next()
}

var cat = function (req, res) {
  console.log('cat')
  res.send('HELLO!')
}

app.get('/', [apple, book, cat])

app.listen(3000, function () { console.log('READY!') })

All 16 comments

Never mind, i see now in the source that this is deprecated. But the deprecation warning does not fire.

The array syntax was deprecated a while back (don't recall why). And personally I want to remove the multiple callback thing now too since we have an easy way to add multiple middleware to a route without repeating. However we don't have that for .use (without making a new router) so there is that.

I must have missed something obvious. Do you have a quick example?

Edit: You mean like this?

app.route('/profile')
    .all(isLoggedIn)
    .all(isVerified)
    .get(profile);

The array thing is mentioned in the 4.x docs, so that is why i tried. Maybe it should be removed, or marked as deprecated :)

Yea, the array thing and the accepting multiple functions is an inconsistency. I might actually want to remove them both now that I think about it.

For routes, you don't need arrays cause you can just do what you showed above. And for the .use case, you can just create a router to provide multiple middleware for a particular subpath.

app.use('/foo', middleware1, middleware2);

Would now be:

var router = express.Router();
router.use(middleware1);
router.use(middleware2);

app.use('/foo', router);

Thoughts @visionmedia @jonathanong ?

Yeah, that seems like a much cleaner way to do it (imo). The multiple argument way inherently feels a bit "wrong" at times, especially when the list of middleware grows.

@defunctzombie as long as it's consistent! People are going to complain though.

@jonathanong complain about what? Not being able to pass in arrays or multiple callbacks? The arrays stuff was already deprecated as far as I could tell. Was there a reason for deprecating it? If so maybe that logic follows for multiple function arguments.

People will always complain.

Was it? People use it. I know an array of paths is deprecated but not sure about middleware.

At least the 4.x documentation should be updated to avoid confusion, since the array method of passing callbacks/middleware is used as a working example.

fixed in rc4

A combination of independent functions and arrays of functions can handle a route.

According to the docs on page http://expressjs.com/en/guide/routing.html the array based middleware should still be valid but it doesn't seem to work.

So either the docs need to be changed or the behaviour has changed again ( <- unlikely )

Btw: this array based grouping of middleware functions was really handy and I don't see a good alternative so far.

Please change the documentation which still shows middlewares being passed as arrays, if it is deprecated.

@php-workx @agauniyal an array of middleware is still supported:

var express = require('express')
var app = express()

var apple = function (req, res, next) {
  console.log('apple')
  next()
}

var book = function (req, res, next) {
  console.log('book')
  next()
}

var cat = function (req, res) {
  console.log('cat')
  res.send('HELLO!')
}

app.get('/', [apple, book, cat])

app.listen(3000, function () { console.log('READY!') })

I use arrays of middleware too without issues.

Sorry for commentin in an old issue. But this doesn't seem to work with Typescript as it complains about req, res, and next having implicitly any type:

const m1: RequestHandler = (req, res, next) => {
  next();
};

const m2: RequestHandler = (req, res, next) => {
  next();
};

router.post('/', [m1, m2], (req, res, next) => { ... }); // Parameter `req`, `res`, and `next` implicitly has an `any` type. ts(7006)

Has this been discussed in other issue?

P.S.: Not an issue with JS, but this does break auto-complete for req, res, and next on editors like VSCode

Hi @ionizer please open a new issue instead of commenting on an issue that has been closed for many years. Opening a new issue will allow for more people to triage your issue and provide help to you directly. You can do this at https://github.com/expressjs/express/issues/new/choose

Was this page helpful?
0 / 5 - 0 ratings

Related issues

haider0324 picture haider0324  路  3Comments

HafidAbnaou picture HafidAbnaou  路  3Comments

Domiii picture Domiii  路  3Comments

extensionsapp picture extensionsapp  路  3Comments

nove1398 picture nove1398  路  3Comments