Published on

How to Make Yup Numbers Accept Nullable Values

Authors
  • Name
    Ripal & Zalak
    Twitter

How to Make Yup Numbers Accept Nullable Values

Yup is a versatile JavaScript schema builder used for value parsing and validation. By default, Yup’s number() method does not accept empty or null values. This can cause validation errors for optional fields. Here’s how you can configure Yup to accept nullable values for numbers.

Problem Description

Consider the following Yup validation schema:

const schema = Yup.object({
  nrOfApples: Yup.number().min(0).max(999),
})

If the nrOfApples field is left blank, Yup will return a validation error, as number() does not accept empty values by default. How can we modify this to allow blank or null values?

Solution

Using nullable(true)

To make a Yup number schema accept null, add the .nullable(true) method:

const schema = Yup.object({
  nrOfApples: Yup.number().min(0).max(999).nullable(true),
})

This tells Yup to treat null as a valid value. However, if the field is left blank, it may still return NaN. To address this, use a transform method.

Using transform for Empty Values

You can use the .transform method to convert empty strings or NaN to null:

const schema = Yup.object({
  nrOfApples: Yup.number()
    .min(0, 'Value must be at least 0')
    .max(999, 'Value must be at most 999')
    .nullable(true)
    .transform((_, val) => (val === '' || isNaN(val) ? null : val)),
})

Here’s how it works:

  • The transform method checks the input value.
  • If the value is an empty string ('') or NaN, it converts it to null.

Full Example

Below is an example of a complete Yup schema with nullable number validation:

import * as Yup from 'yup'

const schema = Yup.object({
  name: Yup.string().required('Name is required'),
  nrOfApples: Yup.number()
    .nullable(true)
    .transform((_, val) => (val === '' || isNaN(val) ? null : val))
    .min(0, 'Value must be at least 0')
    .max(999, 'Value must be at most 999'),
})

const validateForm = async (formData) => {
  try {
    await schema.validate(formData, { abortEarly: false })
    console.log('Validation Passed:', formData)
  } catch (errors) {
    console.error('Validation Errors:', errors)
  }
}

validateForm({ name: 'John', nrOfApples: '' })

FAQs

1. Why does Yup treat empty strings as invalid for numbers?

Yup’s number() method expects a valid number by default. Empty strings ('') are not considered numbers and need to be explicitly transformed to a valid value, such as null.

2. What happens if I use required() with nullable(true)?

The required() method overrides nullable(). If a field is required, it cannot accept null values, even if nullable(true) is set.

3. Can I set a default value for nullable fields?

Yes, use the .default() method to assign a default value for nullable fields:

const schema = Yup.object({
  nrOfApples: Yup.number()
    .nullable(true)
    .default(0)
    .transform((_, val) => (val === '' || isNaN(val) ? null : val)),
})

4. Can I use this approach with other types?

Yes, the nullable and transform methods can be used with other Yup types, such as string, date, or boolean.