Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

checkSchema - custom validator and exists errorMessage #527

Closed
andrey-hohlov opened this issue Feb 16, 2018 · 17 comments
Closed

checkSchema - custom validator and exists errorMessage #527

andrey-hohlov opened this issue Feb 16, 2018 · 17 comments

Comments

@andrey-hohlov
Copy link

Hi!

I'm trying to use Schema Validation with 5.0.0.

  1. custom validator throw validation error validatorCfg.validator is not a function
  2. For exists param errorMessage ignored
checkSchema({
  title: {
    in: ['body'],
    exists: {
      errorMessage: 'title is required', // <- doesn't work
    },
    custom(value) { // <- doesn't work
      console.log(value);
      return true;
    }
  },
  password: {
    isLength: {
      errorMessage: 'Password should be at least 7 chars long', // <- works
    },
  },
});

customValidators param and all in this doc section https://github.com/ctavan/express-validator#legacy-api are deprecated...

What am I doing wrong?

@gustavohenke
Copy link
Member

Hm, the exists one is strange, by "doesn't work" do you mean the error message is still Invalid value? It shouldn't be, so there might be something else wrong with your setup.

The custom one should be specified by passing options.
I will add an example to help clear future questions about it.

This is a very minimal app with both validators working:

const { checkSchema, validationResult } = require('./check');

const express = require('express');
const app = express();
app.use(express.json());
app.post('/*', checkSchema({
  foo: {
    in: ['body'],
    exists: {
      errorMessage: 'bla'
    },
    custom: {
      options: value => (value || '').startsWith('foo')
    }
  }
}), (req, res) => {
  res.json(validationResult(req).array());
});

app.listen(3000);

@andrey-hohlov
Copy link
Author

andrey-hohlov commented Feb 17, 2018

@gustavohenke thank you!

It's all right with exists, my mistake.
Also, I tried custom with async function and it works too.

Is there a way to use multiple custom validators with different error messages?
Like:

check('password')
  .custom(value => someValidationFunction(value))
  .withMessage('Some validation error message')
  .custom(value => anotherValidationFunction(value))
  .withMessage('Another validation error message')

@gustavohenke
Copy link
Member

If you don't use schema, then yes.

@andrey-hohlov
Copy link
Author

@gustavohenke same story for custom sanitizers?

Schema better for using, chains ugly :(

@gustavohenke
Copy link
Member

Yes, the same for custom sanitizers.

@mohsincynexis
Copy link

mohsincynexis commented Mar 20, 2018

not working with async.js here is my code:

email: {
    errorMessage: 'Please enter a valid email address',
    isEmail : true,
    trim: true,
    custom: {
        options: (value) => {
        async.waterfall([
            function(callback) {
                User.findByEmail(value, function (err, result) {
                    if (err) {
                        callback(new Error("failed getting something:" + err.message));
                        // we should return here
                    }
                    // since we did not return, this callback still will be called and
                    // `processData` will be called twice
                    callback(null, result);
                });
            },
            //processData
        ], function (err, result) {
            if(err) {
                return false;
            }
            else{
                if(result.length==0){
                    console.log('record not found');
                    return false;
                }else{
                    console.log('record found');
                    return true;
                }
            }
        }
        )
        },
        errorMessage: 'email taken',
    }
}

Please help me to resolve this I always get the 'email taken message'.

@gustavohenke
Copy link
Member

You must return a promise.

@mohsincynexis
Copy link

can you please guide me how can I do this, coz I am new in node js. PLEASE HELP

@gustavohenke
Copy link
Member

gustavohenke commented Mar 20, 2018

Sorry, I don't know about async.js, but you could post this on StackOverflow with the relevant tags. I'm pretty sure the popularity of async.js will make it easy for you to find get answers quickly though.

@mohsincynexis
Copy link

Okay Thanks a lot gustavohenke!!!
I did the same and it started working now here is my code, if there is any mistake please let me know
`
email: {
errorMessage: 'Please enter a valid email address',
isEmail : true,
trim: true,
custom: {
options: (value) => {
return new Promise(function (resolve, reject) {

                User.findByEmail(value, function (err, result) {
                    if (err) {

                        reject(err);

                    }else{
                        resolve(result)
                    }

                });

            }).then(function (result) {
                if(result.length==0){
                    console.log('record not found');
                    return true;
                }else{
                    console.log('record found');
                    return false;
                }
            })
            },
            errorMessage: 'email taken',
        }
    }`

@dpkshrma
Copy link

@gustavohenke I think the usage for custom should be more clearly documented for checkSchema. Any new user who has used check api (since it very much follows) would assume that value for custom key will be a validator function and not an object.

@gustavohenke
Copy link
Member

Fair enough @dpkshrma.
I would say that this is for every validator then? As we consider any validator function param as an option.

@prettymuchbryce
Copy link

prettymuchbryce commented Jun 29, 2018

@gustavohenke Would it not be possible to allow for custom validators and sanitizers in the fields themselves without using a custom object? Could they be inferred from the values defined already in the expressValidator middleware under customValidators. Personally I would prefer to define custom sanitizers and validators once, and then re-use them throughout the project.

For example:

app.use(expressValidator({
  customValidators: {
    myCustomValidator: value =>  true,
  }
}));

Then in the checkSchema middleware.

router.get("/:myParam",
  checkSchema({
    myParam: {
      in: ['params'],
      isString: true,
      myCustomValidator: true
    },
  }),
...

Would you entertain a pull request with such a change?

@gustavohenke
Copy link
Member

gustavohenke commented Jun 29, 2018

Hi @prettymuchbryce, it's out of the plans for the check APIs to have any interactions with the legacy ones (the expressValidator middleware you used), as they are gonna be phased out at some point.
The less state we store in the request, the better.

What I would like to do instead is something like validatorResult.withDefaults(options): a factory for the check API that you can inject custom defaults, like validators:

// Use these, don't import them from `express-validator/check`!
const { check, checkSchema, validationResult, etc } = createCheckAPI({
  customSanitizers: { ... },
  customValidators: { ... },
  someOtherOption: value
})

For now, what you can do is move these validators or schemas (or whatever you like) into separate files, and import them in your schemas.

@prettymuchbryce
Copy link

prettymuchbryce commented Jun 29, 2018

@gustavohenke I understand. I didn't realize this middleware was legacy.

I like your proposal, and I feel it would solve the problem with the awkwardness of the custom fields, as well as solve the problem of allowing multiple custom validators/sanitisers all without polluting the request object.

Do you have plans to do this yourself in the near term? Would you be open to receiving a pull request for this enhancement?

@gustavohenke
Copy link
Member

Yes, any PRs are welcome!
I may not be able to have this solved so soon by myself, as there are other issues that are more pressing (eg #439) and have been on the wait queue for some time.

@lock
Copy link

lock bot commented May 31, 2019

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@lock lock bot locked as resolved and limited conversation to collaborators May 31, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants