Search code examples
javascriptnode.jsexpressrestcrud

Why does the 4th argument in my express middleware function only break it in certain conditions?


I am new to node/express and came across something strange to me. If I include a 4th "value" parameter on certain middleware functions, they wont work, while others do. I've read adding a 4th parameter will count it as Error Handling middleware, but I'm not sure if this is the same thing. Here is what I read: Express.js middleware extra (fourth) argument . I suspect it has something to do with middleware1 being passed in as a param while middleware2 is being past into a post, but I'm lost as to how it works. Any help explaining would be greatly appreciated, thank you.

controller.js

exports.middleware1  = (req, res, next, val) => {
  if (Number(req.params.id) > tours.length) {
    return res.status(404).json({
      status: 'failed',
      message: 'Invalid ID',
    });
  }
  next();
};

exports.middleware2 = (req, res, next) => {
  if (!req.body.name || !req.body.price) {
    return res.status(400).json({
      status: 'fail',
      message: 'Missing name or price',
    });
  }

  next();
};

routes.js

router.param('id', middleware1) // this one works even if I include the "val" parameter
router.post(middleware2, createPost) // this one wont work if I include the "val" parameter as my 4th parameter

Solution

  • When you use a middleware function router.param('id', middleware1), express expects four parameters: req, res, next, val:

    router.param('id', (req, res, next, val) => {
      next();
    });
    

    When you use a middleware function router.post(middleware2, createPost), express expects only three parameters: req, res, next:

    router.post((req, res, next, val) => {
      next();
    }, createPost);
    

    Source: router.param(name, callback)

    Adds callback triggers to route parameters, where name is the name of the parameter and callback is the callback function. Although name is technically optional, using this method without it is deprecated starting with Express v4.11.0

    The parameters of the callback function are:

    • req, the request object.
    • res, the response object.
    • next, indicating the next middleware function.
    • The value of the name parameter.
    • The name of the parameter.

    Middleware functions can take different numbers of parameters, and the number of parameters a middleware function has determines its behavior.

    Regular middleware: 3 parameters

    app.use((req, res, next) => {
      next();
    });
    

    Error handling middleware: 4 parameters

    app.use((err, req, res, next) => {
      res.sendStatus(500);
    });