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

notRequired() with empty string causes validation to fail #313

Open
dan003400 opened this issue Aug 20, 2020 · 15 comments
Open

notRequired() with empty string causes validation to fail #313

dan003400 opened this issue Aug 20, 2020 · 15 comments

Comments

@dan003400
Copy link

There is no way to make a field optional but validate when not an empty string.

Yup.string().phone(true, false, 'Phone not valid').notRequired()

@abhisekp
Copy link
Owner

@dan003400 Could you please look into the lib code and file a PR for this if possible?

Thank You 😃

@trycrmr
Copy link

trycrmr commented Oct 7, 2020

@dan003400 I think this works as a workaround:

const schema = Yup.object().shape({
  phone: Yup.string().when("isPhoneBlank", {
    is: false,
    then: Yup.string().phone(),
    otherwise: Yup.string(),
  }),
});

Using .when() referencing a sibling boolean key/value pair let's you check if the phone string is blank, and only use yup-phone if it isn't.

On the off chance you're using Formik doing this quick check whenever validations happen seems to be working alright:

onChange={(e) => {
  if (values.phone && values.phone.length > 0) {
    setValues(
      { ...values, isPhoneBlank: false },
      false
    );
  } else {
    setValues(
      { ...values, isPhoneBlank: true },
      false
    );
  }
  handleChange(e);
}}

@KmaCoder
Copy link

KmaCoder commented Nov 26, 2020

Or actually a better workaround without creating additional values like 'isPhoneBlank' is to add new method to yup where we can conditionally validate different schemas if value is blank:

Yup.addMethod(Yup.string, 'validatePhone', function () {
  return this.test('test-phone', "This phone number doesn't seem to look valid", value => {
    if (value) return this.phone().isValidSync(value)
    return true
  })
})

Or simply use .test method in schema without adding new method:

Yup.string().test('test-phone', "This phone number doesn't seem to look valid", value => {
    if (value) return this.phone().isValidSync(value)
    return true
  })

@nightness
Copy link

nightness commented Jan 6, 2021

Add this to the repo please

        // This is what .required() is for
        if (!value || ((typeof(value) == 'string') && value.length == 0)) return true

        try {
            const phoneNumber = phoneUtil.parseAndKeepRawInput(value, countryCode)

@abhisekp
Copy link
Owner

abhisekp commented Jan 9, 2021

@nightness Would you like to file a PR with the given code?

@nightness
Copy link

@abhisekp Just did the PR.

@nightness
Copy link

@abhisekp corrected my PR errors.

@abhisekp
Copy link
Owner

Thanks for your PR @nightness

@JulienRst
Copy link

Hi folks, I really need this change for a project,
Can I be of any help to make this PR merged asap ?
(already looked at @nightness changes and it seems fine to me !)

@abhisekp
Copy link
Owner

abhisekp commented Mar 9, 2021

@JulienRst Kindly, review #461 (comment)

@abhisekp
Copy link
Owner

Kindly, reach out to me in any of the platforms given below to volunteer for maintaining this repository.
https://about.me/abhisekp

@kferolinomersoft
Copy link

kferolinomersoft commented Sep 6, 2021

Or actually a better workaround without creating additional values like 'isPhoneBlank' is to add new method to yup where we can conditionally validate different schemas if value is blank:

Yup.addMethod(Yup.string, 'validatePhone', function () {
  return this.test('test-phone', "This phone number doesn't seem to look valid", value => {
    if (value) return this.phone().isValidSync(value)
    return true
  })
})

Or simply use .test method in schema without adding new method:

Yup.string().test('test-phone', "This phone number doesn't seem to look valid", value => {
    if (value) return this.phone().isValidSync(value)
    return true
  })

To add here from @KmaCoder

const phoneSchema = yup.string().phone('US', true);

const validationSchema = yup.object({
   ...otherValidations,
   phone: yup.string().test('test-phone', 'Invalid format', (value) => {
      if (value) return phoneSchema.isValidSync(value);
      return true;
  }),
});

@ptitdam2001
Copy link

Clone #718

@rksainath
Copy link

To avoid empty field validation try the below solution.

const schema = Yup.object().shape({
 phone: Yup.string().when('phone', {
        is: (value) => value?.length > 0,
        then: Yup.string().phone(),
        otherwise: Yup.string(),
      }),
 },[['phone', 'phone']]);

The reason for duplicating the dependencies is to avoid cyclic dependency errors. Check this StackOverflow discussion for more details.

@codenameberyl
Copy link

This was how I fixed empty field validation.

const [phone, setPhone] = useState()

function validatePhone() {
        if (phone) {
            return yup.string().phone(null, true, "Invalid Phone Number")
        } else {
            return yup.string().ensure()
        }
}

const validationSchema = yup.object({
   ...otherValidations,
   phone: validatePhone(),
})

<PhoneInputWithCountry
      className="form-control"
      defaultCountry="US"
      name="phone"
      id="phone"
      value={phone}
      onChange={setPhone}
      control={control}
  />

According to yup string.ensure() documentation

string.ensure(): Schema
Transforms undefined and null values to an empty string along with setting the default to an empty string.

I hope this works for someone. All thanks to @abhisekp. Happy coding.

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

Successfully merging a pull request may close this issue.

10 participants