Neil Cooper
Neil Cooper

Reputation: 102

chaining custom validators in express-validator?

i thought this was pretty straightforward, but i've a feeling that chaining the custom validator with existing ones causes something strange to happen with the req object, which seems to be undefined:

req.checkBody('Game18awayScore', 'must be between 0 and 30').isInt({min:0, max:30}).custom((value,{ req }) => {
        console.log(something);
        if (Math.abs(value - req.body.Game18homeScore) < 2){
          if (value < 30 && req.body.Game18homeScore < 30){
            throw new Error("winning score isn't 2 greater than losing score");
          }
        }
      });
      req.checkBody('homeMan1', 'Please choose a player.').notEmpty().custom((value,{req}) => {
        if (value != 0){
          if (value == req.body.homeMan2 || value == req.body.homeMan3 || value == req.body.awayMan1 || value == req.body.awayMan2 || value == req.body.awayMan3){
            throw new Error("can't use the same player more than once")
          }
        }

      });

but i just keep getting: TypeError: Cannot destructure propertyreqof 'undefined' or 'null'.

The first custom is checking that there's a difference of at least two between the two values, unless one of the values is 30.

The second custom is checking that one value isn't being used in the other 5 options.

I should add, this block of code is in a validator Function:

function validateScorecard (req,res,next){ [all my validations for the form including the ones above] }

which is then included in the route: app.post('/scorecard-beta',validateScorecard, fixture_controller.full_fixture_post);

any ideas?

Upvotes: 0

Views: 2364

Answers (1)

gustavohenke
gustavohenke

Reputation: 41440

Using .custom() to specify an inline validator like this doesn't work when you are using the legacy API (eg req.checkBody(...).custom()).

The legacy API has had support for custom validators in a quite different way for some years:
You specify them as options in your express-validator middleware, and they are made available when you use req.checkBody(...).
These can then receive additional arguments other than the field's value.

Example:

app.use(expressValidator({
    customValidators: {
        isMagicNumber(value, additionalNumbers) {
            return value === 42 || additionalNumbers.includes(value);
        }
    }
}));

app.post('/captcha', (req, res, next) => {
    // world's safest captcha implementation
    req.checkBody('answer').isMagicNumber();
    req.checkBody('answer').isMagicNumber([req.user.age]);
});

The .custom() call kinda works because the method is there, but internally in the legacy API, express-validator doesn't know how you defined it.

Your solutions?

  • Keep using it like that, but refrain from using additional args, as that would come against what is documented for .custom().
  • stop using the legacy API, as it is deprecated and will be removed eventually.

Upvotes: 1

Related Questions