Yup Number Validation: Allow Empty String

With min and max number validation.

1. Allow Number & Empty String

To validate a number with yup and still allow an empty string, use the following schema:

const numberSchema = number()
  .nullable()
  .transform((value, original) => (original === "" ? null : value));

In this schema, if the original value is an empty string "", it will result in NaN when casting to a number. We return null from the transform step, an allowed value in that case. For all other cases, except for null itself and undefined (which can disallowed by .required()), we return the actual value, which is supposed to be a number.

Examples

try {
  console.log(numberSchema.validateSync(7));
} catch (e) {
  console.log(e.errors);
}

try {
  console.log(numberSchema.validateSync("7"));
} catch (e) {
  console.log(e.errors);
}

try {
  console.log(numberSchema.validateSync(null));
} catch (e) {
  console.log(e.errors);
}

try {
  console.log(numberSchema.validateSync(undefined));
} catch (e) {
  console.log(e.errors);
}

try {
  console.log(numberSchema.validateSync(""));
} catch (e) {
  console.log(e.errors);
}

try {
  console.log(numberSchema.validateSync({}));
} catch (e) {
  console.log(e.errors);
}

The above calls will result in:

7
7
null
undefined
null
[
  'this must be a `number` type, but the final value was: `NaN` (cast from the value `{}`).'
]

Notice the second last null, coming because of passing the empty string “”.

2. Include Min & Max Validation

To the above code, we make this slight modification:

const MIN = 10;
const MAX = 1000;
const numberSchema = number()
  .nullable()
  .transform((value, original) => (original === "" ? null : value))
  .test("min max", `value must be from ${MIN} to ${MAX}`, function (value) {    
    if (!value) return true;
    return value >= MIN && value <= MAX;
  });

Here, we’re adding our custom logic for min max, as .min() and .max() throw casting errors since the transform step has not been reached yet. In the test() method, we confirm that the value is not undefined, null, or """, meaning it must be a valid number. So we compare it against MINandMAXvalues and returntrueorfalse`.

Examples


try {
  console.log(numberSchema.validateSync(7));
} catch (e) {
  console.log(e.errors);
}

try {
  console.log(numberSchema.validateSync("7"));
} catch (e) {
  console.log(e.errors);
}

try {
  console.log(numberSchema.validateSync(77));
} catch (e) {
  console.log(e.errors);
}

try {
  console.log(numberSchema.validateSync("77"));
} catch (e) {
  console.log(e.errors);
}

try {
  console.log(numberSchema.validateSync(null));
} catch (e) {
  console.log(e.errors);
}

try {
  console.log(numberSchema.validateSync(undefined));
} catch (e) {
  console.log(e.errors);
}

try {
  console.log(numberSchema.validateSync(""));
} catch (e) {
  console.log(e.errors);
}

try {
  console.log(numberSchema.validateSync({}));
} catch (e) {
  console.log(e.errors);
}

Results in:

[ 'value must be from 10 to 1000' ]
[ 'value must be from 10 to 1000' ]
77
77
null
undefined
null
[
  'this must be a `number` type, but the final value was: `NaN` (cast from the value `{}`).'
]



See also

When you purchase through links on techighness.com, I may earn an affiliate commission.