Orodan
Orodan

Reputation: 1047

Yup how to validate mandatory fields on null object

I have a problem regarding the validation of mandatory fields which are properties of a (possibly) null object.

Here is an example schema :

object().shape({
   catalog: {
      brand: string().required()
   }
})

If I try to validate the following object against this schema, I get the expected error : brand is required. From what I understood, there is a default value created for undefined object which mimics the shape of the object in the schema. This is the behavior I expected and what I want.

{ catalog: undefined }

// "catalog.brand is a required field"

But in my case, I don't receive an object with undefined, but with null. And I can't figure out how to manage the same result with a null value.

{ catalog: null }

// No error on catalog.brand

Manually casting null to undefined is out of the question as there is a good reason why I receive null.

Here is a codesandbox which reproduces my use case :

https://codesandbox.io/s/yup-playground-tbfcj

I would really appreciate a bit of help on this, thanks :)

Upvotes: 4

Views: 14119

Answers (4)

obertuccini
obertuccini

Reputation: 123

Adding the .default(null) method along with .nullable() worked for me.

const parentValidator = Yup.object({
  personData: personDataValidator,
  data: Yup.object({
    workshift: Yup.array()
      .of(Yup.string().matches(/x|-/g, "Local de trabalho inválido"))
      .required("Turno de trabalho obrigatório")
      .typeError("Turno de trabalho inválido"),
    workplace: Yup.string()
      .required("Local de trabalho obrigatório")
      .typeError("Local de trabalho inválido"),
    email: Yup.string()
      .required("Email obrigatório")
      .typeError("Email inválido"),
  }),
})
  .default(null)
  .nullable();

Upvotes: 0

jhrr
jhrr

Reputation: 1730

Here's a less mindbending way to do it than the other answer. This allows you to keep the required directive on the subfield whether or not the parent schema/field containing it is empty at validation time.

yup.object().shape({
  field: yup.object().shape({
    subfield: string().required(),
  }).default(undefined),
});

// Or...

yup.object().shape({
  field: yup.object().shape({
    subfield: string().required(),
  }).default(null).nullable(),
});

One difference between the two is that when you validate data over each of these schemas and field is missing, if you also pass in stripUnknown, in the first case the field will be totally removed from the validated result, but in the second case the field will still show up but with value null.

Upvotes: 0

Amedeo Zucchetti
Amedeo Zucchetti

Reputation: 11

Try adding strict() on your object schema

object().shape({
   catalog: {
      brand: string().required()
   }
}).strict();

Upvotes: 1

Deepak Kadarivel
Deepak Kadarivel

Reputation: 189

The solution is to include both nullable() and required() to the shape.

Example

const requiredOption = Yup.object()
  .shape({
    value: Yup.string(),
    label: Yup.string(),
  })
  .nullable()
  .required('This field is required.');

Upvotes: 8

Related Questions