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

Documentation about custom validators calling other validators #74

Open
amangeot opened this issue Jun 5, 2017 · 1 comment
Open

Documentation about custom validators calling other validators #74

amangeot opened this issue Jun 5, 2017 · 1 comment

Comments

@amangeot
Copy link

amangeot commented Jun 5, 2017

Hello,
I am wondering how to implement a custom validator which checks the type of an object.

The documentation is very clear for custom validators which do not call other validators, but it is quite unclear how validators should be called from custom validators. I have tried using PropTypes.checkPropTypes but couldn't make it happen.


Here is a solution that seems to be working:

// const customPropTypes = {...}

function (props, propName, componentName, ...rest) {
  if (props[propName]) {
    const { type } = props[propName]

    if (!type) {
      return new Error(`Invalid prop \`${propName}\` supplied to \`${componentName}\`. Missing type.`)
    } else if (Object.keys(customPropTypes).indexOf(type) === -1) {
      return new Error(`Invalid prop \`${propName}\` supplied to \`${componentName}\`. Unhandled type: ${type}.`)
    }

    return customPropTypes[type](props, propName, componentName, ...rest)
  }

  return null
}

Another challenge is to make the custom validator chainable in order to chain it with .isRequired. A blog post suggested to implement it this way:

const ANONYMOUS = '<<anonymous>>'

export default function createChainableTypeChecker (validate) {
  function checkType (isRequired, props, propName, componentName, ...rest) {
    componentName = componentName || ANONYMOUS

    if (props[propName] == null) {
      // var locationName = ReactPropTypeLocationNames[location]
      if (isRequired) {
        // return new Error(`Required ${locationName} \`${propName}\` was not specified in \`${componentName}\`.`)
        return new Error(`Required \`${propName}\` was not specified in \`${componentName}\`.`)
      }
      return null
    } else {
      return validate(props, propName, componentName, ...rest)
    }
  }

  var chainedCheckType = checkType.bind(null, false)
  chainedCheckType.isRequired = checkType.bind(null, true)

  return chainedCheckType
}

I commented out the part related to locationName as I could not figure out where ReactPropTypeLocationNames


Is it the way to solve to implement custom validators which call other validators ?

@jharris4
Copy link

Sounds like you may need to use the checkPropTypes function if you want to programatically call other validators from a custom validator: https://github.com/facebook/prop-types#proptypescheckproptypes

Also, note that using .isRequired even on a custom validator will cause the validator to never be executed. Instead an error message is output before the validator is even run.

There's a PR to fix this (#90), so that will change if it ever gets merged.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants