Skip to content

schema validation with array parameter throws odd error when a single element is passed #704

Closed
@ericsnap

Description

@ericsnap

As mentioned in this SO question, I was wondering how to handle optional, multi-value query parameters.
I want to check that the foo parameter is alphanumeric.
The query ?foo=bar&foo=baz yields req.query.foo = ['bar', 'baz'].
If I want to use express-validator to ensure that all values passed are alphanumeric, I see some odd error messages.

Here is my very simple code:

const express = require("express");
const { checkSchema, validationResult } = require("express-validator/check");

const app = express();

app.get(
    "/a",
    checkSchema({
        foo: {
            in: "query",
            isAlphanumeric: true,
            optional: true,
        },
    }),
    handler
);

app.get(
    "/b",
    checkSchema({
        'foo.*': {
            in: "query",
            isAlphanumeric: true,
            optional: true,
        },
    }),
    handler
);

app.listen(8888, () => {
    console.log(`listenning`);
});

function handler(req, res) {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
        res.status(400).send({ errors: errors.array() });
    } else {
        res.send({
            foo: req.query.foo,
        });
    }
}

if I call it with:
curl 'localhost:8888/a?foo=barone&foo=bar%20two'
I get
{"foo":["barone","bar two"]}
because /a only validates 1 value of foo.

if I call it with:
curl 'localhost:8888/b?foo=barone&foo=bar%20two'
I get
{"errors":[{"location":"query","param":"foo[1]","value":"bar two","msg":"Invalid value"}]}
which is to be expected.

Unexpected behavior
However, things get wonky when I only pass a single value to foo.

if call
curl 'localhost:8888/a?foo=bar%20two'
I get
{"errors":[{"location":"query","param":"foo","value":"bar two","msg":"Invalid value"}]}
which is correct

but if I call
curl 'localhost:8888/b?foo=bar%20two'
I get
{"errors":[{"location":"query","param":"foo[3]","value":" ","msg":"Invalid value"}]}

That last message is odd. I would expect:

  • either a simple param: 'foo'
  • or somewhat detect the wildcard and say param: 'foo[0]' in the case of a single element

I put together a runkit notebook if you and to check it out live or hit the live endpoint.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions