Required Field Validation - Ensuring a Field is Mandatory Based on Property Length Exceeding 0

When dealing with a form that includes lists of countries and provinces, there are specific rules to follow:

  1. The country field/select must be filled out (required).
  2. If a user selects a country that has provinces, an API call will fetch the list of provinces.
  3. If provinces exist for the selected country, the provinces field/select becomes required.
  4. If no provinces are found for the selected country after the API call, the provinces field/select is not required.

I am currently developing this functionality using React Hooks...

const validationSchema = yup.object().shape({
    country: yup
      .object()
      .required(t("common.validation.field_required"))
      .nullable(),
    province: yup.object().when() // How to validate provinces to be required?
});


const [provinces, setProvinces] = useState<Province>([]);

const fetchProvinces = (country: Country) => {
 // Code for API fetch ...
 setProvinces(apiResult);
}

...
return (
 ...
 <Autocomplete id="countries-list" options={countriesList} onChange={fetchProvinces} ... />
 <Autocomplete id="provinces-list" options={provincesList} ... />
 ...
);

Is there a way to use YUP to make the provinces-list field mandatory only if there is content in the provinces property (provinces.length > 0)?

Answer №1

After facing a dilemma, I came up with a clever workaround by introducing a fictitious property named hasProvinces while configuring the form properties. Once we choose a country with provinces, we flag hasProvinces as true. With the power of yup, I can now leverage the "when" clause. Here's an example:

interface MyForm {
   country: Country;
   hasProvinces: boolean;
   province: Province;
}
...

const validationSchema = yup.object().shape({
    country: yup
      .object()
      .required(t("common.validation.field_required"))
      .nullable(),
    hasProvinces: yup.boolean(),
    province: yup.object().when("hasProvinces", {
      is: true,
      then: yup
        .object()
        .required(t("common.validation.field_required"))
        .nullable(),
      otherwise: yup.object().notRequired().nullable(),
    })
});

const [countries, countriesList] = useState<Country[]>([]);
const [provinces, setProvinces] = useState<Province[]>([]);

const [formValues, setFormValues] = useState<MyForm>(initialFormValues);

const fetchProvinces = (country: Country) => {
 const provinces = ... // Code for API fetch

 if(provinces.length > 0){
    setFormValues({...formValues, hasProvinces: true});
    setProvinces(provinces);
 }else{
    setFormValues({...formValues, hasProvinces: false});
    setProvinces([]);
 }
}

...
return (
 ...
 <Autocomplete id="country" options={countriesList} onChange={fetchProvinces} ... />
 <Autocomplete id="province" options={provincesList} ... />
 ...
);

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Using jQuery to display checkbox text even when it is not directly adjacent to the checkbox

I'm struggling to display the checked value text as shown in the image without any refresh or click. Can anyone offer assistance? This is my PHP dynamic form: <div class="products-row"> <?php $tq=$conn->query("select * from os_tiffen ...

Creating a unique LinearProgress component using React and MaterialUI with a beautiful

I am looking to enhance the appearance of MaterialUI's LinearProgress element by creating a gradient design for the completeness bar. My goal is to have the left side of the bar display color A and the right side show color B, with the transition betw ...

Change a Typescript class into a string representation, utilizing getter and setter methods in place of private variables

Below is a snippet of TypeScript code: class Example { private _id: number; private _name: string; constructor(id: number, name: string) { this._id = id; this._name = name; } public get id(): number { return t ...

Ways to analyze users who have clicked a button

After a user registers, they are automatically taken to /proto where they can view a list of animals available for adoption. However, the challenge lies in identifying the specific user who clicked the button (as this information must be associated with th ...

Guide to deploying a React application - paths requiring adjustments

I am a novice developer looking to learn more. Recently, I decided to clone Emilio Quintanas Servitodo APP into my own repository. After downloading the repo, I attempted to use gh-pages with npm to build and deploy the APP. However, I encountered an issue ...

Determine the instance's name as a string in JavaScript

Currently, I am utilizing Three.js in combination with javascript. Upon running the following line of code: console.log(this.scene.children[1]) I receive the following output in the console within Chrome: https://i.stack.imgur.com/6LBPR.png Is there a w ...

Is there a way in Angular Material to consistently display both the step values and a personalized description for each step?

Is there a way to display both numerical step values and corresponding custom text in Angular Material? I prefer having the number at the top and the descriptive text at the bottom. Check out this image for reference: https://i.stack.imgur.com/LGMIO.png ...

The React Router Dom V6 triggers loaders as soon as the router is initialized

I'm currently working on implementing routing into my application using react-router-dom V6, specifically utilizing the new createBrowserRouter function and RouterProvider component. The issue I'm facing is that when attempting to integrate a lo ...

Is there a way to ensure that the table headers are printed on every page when using Google Chrome

When printing documents in Chrome browser, the table header (thead) does not appear on every page. I want to ensure that the table header is displayed on each printed page, just like it is done with IE and Firefox. However, Chrome does not support this fea ...

Why is it that I am unable to retrieve a value from useContext?

How come I am unable to retrieve a value from useContext? I have already made an update. components/useContext/index.js import React, { useState } from "react"; import Article from "./article"; import status from "./status"; ...

The CSS function imported from '@emotion/react' may encounter compatibility issues with styling components from Material-UI using the styled method

When using the css function imported from '@emotion/react', you may encounter different results depending on how it is implemented. Take a look at the following examples: const Button = styled('button')` ${css`background-color: blue`} ...

gRaphael - the struggle of animating a line chart

Encountering an issue with the gRaphael javascript line chart library. Creating a line chart from a CSV file with five columns (# of minutes, time, waiting time, in treatment, closed, in location). Previously drew full chart without animation successfull ...

Creating interactive tabs within the HTML document with AngularJS

Trying to customize the tab layout on my HTML page and I have a code similar to this: <form name="requestForm"> <div class="form-group col-md-6 md-padding"> <div class="text-primary"> <h3>Create Request</h3> ...

I am wondering if it is feasible for a POST route to invoke another POST route and retrieve the response ('res') from the second POST in Express using Node.js

Currently, I have a POST route that triggers a function: router.route('/generateSeed').post(function(req,res){ generate_seed(res) }); UPDATE: Here is the genrate_seed() function function generate_seed(res) { var new_seed = lightwallet. ...

Service function in Angular 2 is returning an undefined value

There are two services in my project, namely AuthService and AuthRedirectService. The AuthService utilizes the Http service to fetch simple data {"status": 4} from the server and then returns the status number by calling response.json().status. On the ot ...

I am experiencing excessive paper skipping in my printer

I have been using the 80 column dot matrix printer. However, after each printout, the paper skips two times resulting in a lot of wasted paper. How can I resolve this issue? Currently, I am only utilizing the window.print() JavaScript function. Are there ...

Getting callback data from a function in the AWS SDK without using asynchronous methods

I have a code snippet that fetches data from AWS using a function: main.js const { GetInstancesByName } = require("./functions"); var operationmode = "getinstances"; if (operationmode == "getinstances") { let getresult = ...

Strange occurrences with HTML image tags

I am facing an issue with my React project where I am using icons inside img tags. The icons appear too big, so I tried adjusting their width, but this is affecting the width of other elements as well. Here are some screenshots to illustrate: The icon wit ...

Error in Next JS: Invalid element type provided. Expected a string for built-in components or a class/function for composite components

Issue encountered while integrating Leaflet JS with Next JS, facing an error indicating that the element type is invalid. Here's the dynamic import of my Map component. /components/MapDir/index.js import dynamic from 'next/dynamic'; const ...

Enhancing collaboration: Seamlessly sharing interface/interface/model files in the integration of

Currently, I am engrossed in developing an application with an Express backend and Typescript whilst utilizing Angular for the frontend. The only snag I'm facing is that I require interface/models files from the backend to be accessible on the fronten ...