{"id":604,"date":"2020-02-16T05:02:28","date_gmt":"2020-02-16T05:02:28","guid":{"rendered":"https:\/\/www.antpace.com\/blog\/?p=604"},"modified":"2025-08-25T14:01:54","modified_gmt":"2025-08-25T14:01:54","slug":"react-js-yup-only-require-an-input-if-another-is-not-empty","status":"publish","type":"post","link":"https:\/\/www.antpace.com\/blog\/react-js-yup-only-require-an-input-if-another-is-not-empty\/","title":{"rendered":"React JS &#038; Yup: only require an input, if another is not empty"},"content":{"rendered":"<p>Typically, I avoid using JS app frameworks, and default to plain vanilla JavaScript. But, in keeping up with what is current &#8211; and working on projects as part of a team &#8211; <a href=\"https:\/\/reactjs.org\/\">React<\/a> is inevitable: &#8220;A JavaScript library for building user interfaces&#8221; . <a href=\"https:\/\/github.com\/jquense\/yup\">Yup<\/a>\u00a0is the go-to form validation library in this context. Its GitHub page calls it &#8220;Dead simple Object schema validation&#8221;.<\/p>\n<p>Yup creates validation schemas for inputs. Create a Yup validation object, and wire it up to a form &#8211; easy.<\/p>\n<h3>The ask<\/h3>\n<p><em>Setting<\/em>: An existing React project, with a signup form. The form includes address inputs. The &#8220;country&#8221; input was not a required field &#8211; it could be left blank. My assignment was to make that field be required, only if the &#8220;state\/territory&#8221; input was not empty. Sounds straight forward.<\/p>\n<p>Here is a sample of the original code:<\/p>\n<pre>export const apValidateMyAddress = () =&gt; {\n  name: yup.string().required(\"Don't leave this blank!!\"),\n  email: yup.string().email(),\n  address: yup:string(),\n  city: yup.string(),\n  state: yup.string(),\n  country: yup.string()\n}\n<\/pre>\n<p>At first, I wasn&#8217;t sure if I should update this schema code directly. I thought about checking if the state field was blank, or not, and applying a different schema object instead. That would have been the wrong approach.<\/p>\n<p><a href=\"https:\/\/github.com\/jquense\/yup#mixedwhenkeys-string--arraystring-builder-object--value-schema-schema-schema\">Doing some research<\/a>, I discovered that the Yup&#8217;s when() method was the solution. It would let me &#8220;adjust the schema based on a sibling or sibling children fields&#8221;.<\/p>\n<p><strong><u>My first attempt was wrong, and didn&#8217;t work:<\/u><\/strong>:<\/p>\n<pre style=\"border: 6px solid red;\">export const apValidateMyAddress = () =&gt; {\n  name: yup.string().required(\"Don't leave this blank!!\"),\n  email: yup.string().email(),\n  address: yup:string(),\n  city: yup.string(),\n  state: yup.string(),\n  country: yup.string().when('state',{\n    is: true,\n    then: yup.string().required('This is a required field.')\n  })\n}\n<\/pre>\n<p>Errors were thrown. Documentation examples were hard to come by, and I was new at this. I wanted the condition to be true if &#8220;state&#8221; was not blank. Setting the &#8220;is&#8221; clause as &#8220;true&#8221; would only work if state was validated as a boolean &#8211; <em>state: yup.boolean()<\/em> . Ultimately, I was able to check that the &#8220;state&#8221; value existed using the value property:<\/p>\n<pre>export const apValidateMyAddress = () =&gt; {\n  name: yup.string().required(\"Don't leave this blank!!\"),\n  email: yup.string().email(),\n  address: yup:string(),\n  city: yup.string(),\n  state: yup.string(),\n  country: yup.string().when('state',{\n    <strong>is: (value: any) =&gt; !!value,<\/strong>\n    then: yup.string().required('This is a required field.')\n  })\n}\n<\/pre>\n<h2>More Conditional Logic<\/h2>\n<p>In another example of validating a field based on the value of another, I leveraged the <code>context <\/code>attribute. This allows you to pass additional data to the validation schema.<\/p>\n<pre>const validOrderQuanitity = await orderQuantitySchema.validate(orderQuantity, {context: previousOrderQuantity, customerType})\n<\/pre>\n<p>Here, for my order quantity to be valid, it needs to be greater than (or equal to) the previous order quantity, but only when the customer type is &#8220;existing&#8221;. Although the order quantity is what is being validated, I need the context of the previous order quantity and the customer type.<\/p>\n<p>In my validation schema, I use a <code>when<\/code> condition to check the customer type and to reference the passed argument:<\/p>\n<pre>export const myValidationSchema = Yup.number().when('$customerType',{ is: 'existing', then: Yup.number().min(Yup.ref('$previousOrderQuantity'), \"Invalid!\")})\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Typically, I avoid using JS app frameworks, and default to plain vanilla JavaScript. But, in keeping up with what is current &#8211; and working on projects as part of a team &#8211; React is inevitable: &#8220;A JavaScript library for building user interfaces&#8221; . Yup\u00a0is the go-to form validation library in this context. Its GitHub page &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/www.antpace.com\/blog\/react-js-yup-only-require-an-input-if-another-is-not-empty\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;React JS &#038; Yup: only require an input, if another is not empty&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":3163,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[55,71,73,104,136,147],"class_list":["post-604","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-web-development","tag-frontend","tag-javascript","tag-js","tag-react","tag-validation","tag-yup"],"_links":{"self":[{"href":"https:\/\/www.antpace.com\/blog\/wp-json\/wp\/v2\/posts\/604","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.antpace.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.antpace.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.antpace.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.antpace.com\/blog\/wp-json\/wp\/v2\/comments?post=604"}],"version-history":[{"count":1,"href":"https:\/\/www.antpace.com\/blog\/wp-json\/wp\/v2\/posts\/604\/revisions"}],"predecessor-version":[{"id":3164,"href":"https:\/\/www.antpace.com\/blog\/wp-json\/wp\/v2\/posts\/604\/revisions\/3164"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.antpace.com\/blog\/wp-json\/wp\/v2\/media\/3163"}],"wp:attachment":[{"href":"https:\/\/www.antpace.com\/blog\/wp-json\/wp\/v2\/media?parent=604"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.antpace.com\/blog\/wp-json\/wp\/v2\/categories?post=604"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.antpace.com\/blog\/wp-json\/wp\/v2\/tags?post=604"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}