Formik's conditional validation feature is not functioning properly

My form includes multiple inputs, one of which is a file input. The number of file inputs can vary:

<EuiFilePicker
 id={`templateFiles.${index}.documentTemplate`}
 name={`templateFiles.${index}.documentTemplate`}
 display="default"                                
 accept=".ftl"
 onChange={event => {setFieldValue(`templateFiles.${index}.documentTemplate`,event[0])}}
/>

I want to make the files required only if a previous input (contactType) has a specific value (LETTER). Here's what I have:

<EuiSelect
 options={Object.values(ContactType)}
 id={'contactType'}
 name={'contactType'}
 label={t('pages.participant.communicate.columns.contactType')}
/>

Where:

export enum ContactType {
  LETTER = 'LETTER',
  CALL = 'CALL',
}

And my validation schema looks like this:

export const projectContactSchema: SchemaOf<ProjectContactDto> = Yup.object().shape({

 {other values...}

  contactType: Yup.mixed()
    .oneOf(Object.values(ContactType))
    .required(i18next.t('pages.participant.communicate.inputs.contactTypeRequired')),

  templateFiles: Yup.array()
    .of(
      Yup.object().shape({
        language: Yup.mixed()
          .oneOf(Object.values(eLanguage))
          .required(i18next.t('pages.participant.communicate.inputs.languageRequired')),
        documentTemplate: Yup.mixed().when('contactType', {
          is: contactType => contactType === 'LETTER',
          then: Yup.mixed().required(i18next.t('pages.participant.communicate.inputs.templateFileRequired')),
          otherwise: Yup.mixed().notRequired(),
        }),
      })
    )
    .unique('Languages should be unique', (val: any) => val.language)
    .notRequired()
    .nullable(),
})

However, this setup does not seem to work as expected. Even when contactType is selected as LETTER, the files are not required. I've tried using different syntax like :

is: 'LETTER',
then: ... 

But the result remains unchanged.

Answer №1

After some trial and error, I managed to resolve the issue by moving the 'when' statement up two levels. It appears that Yup is unable to check conditions when they are nested.

templateFiles: Yup.array()
    .when('contactType', {
      is: contactType => contactType === 'LETTER',
      then: Yup.array().of(
        Yup.object().shape({
          language: Yup.mixed()
            .oneOf(Object.values(eLanguage))
            .required(i18next.t('pages.participant.communicate.inputs.languageRequired')),
          documentTemplate: Yup.mixed().required('test'),
        })
      ),
      otherwise: Yup.array().of(
        Yup.object().shape({
          language: Yup.mixed()
            .oneOf(Object.values(eLanguage))
            .required(i18next.t('pages.participant.communicate.inputs.languageRequired')),
          documentTemplate: Yup.mixed().notRequired(),
        })
      ),
    })

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

Tips for retrieving the text from a POST request in C#

I have a basic Angular form that allows users to upload a file along with a description. constructor(private http: HttpClient) { } upload(files) { if (files.length === 0) return; const formData: FormData = new FormData(); var filedesc ...

How to bring in a module from another package in Angular 4

This is a fundamental query. As an individual just starting with Angular and npm, this may seem like a basic question for some. However, despite extensive research, I haven't been able to find a solution. Before embarking on a project, I want to cre ...

The Interface in TypeScript will not function properly when used on a variable (Object) that has been declared with the value returned from a function

I am currently in the process of developing an application using Ionic v3. Strangely, I am encountering issues with my interface when trying to assign a variable value returned by a function. Here is an example that works without any problems: export int ...

Enum-Based Object Indexing

The structure I am currently working with is as follows; import data from "../data.min.json"; export enum TileType { tree = 'tree', rock = 'rock' } interface MapTile { walkable: boolean; positions: number[][]; } exp ...

Developing an Angular 2 Cordova plugin

Currently, I am in the process of developing a Cordova plugin for Ionic 2. The plugin is supposed to retrieve data from an Android device and display it either on the console or as an alert. However, I am facing difficulty in displaying this data on the HT ...

When debugging tests in VSCode Mocha with typescript, the debugger follows through the transpiled file rather than the original source .ts file

Whenever I initiate the debugging process for my mocha tests with the provided configuration, Visual Studio Code ends up navigating through the transpiled code rather than the original TypeScript code. Is there a specific setting that needs to be adjuste ...

How can I use React to create a dictionary that modifies several values depending on a single property?

I am looking for a more efficient way to handle the following code in my component example. I have a list component that can display different types of animals such as dogs, cats, and bunnies with specific visual changes and functionality from the API. exp ...

When utilizing the Turf.nearPoint() function, it is important to consider the type of point being used. The documentation for Turf.nearestPoint() appears to be inaccurate

I have some code that needs to be transcribed from another system, so unfortunately I can't easily share it here. If I could, I would just post the entire project. Recently, I attempted to integrate into our project but encountered error messages. T ...

Tips for automatically scrolling to a specific position on a page after displaying a form that has errors

Within the realm of symfony/twig, I encounter a contact page with fields for name and email address, along with validation checks in place. The form resides at the bottom of the page and upon submission, I wish to redirect the user back to the bottom secti ...

GPT Open-Source Initiative - Data Ingestion Challenge

Seeking assistance with setting up the following Open Source project: https://github.com/mayooear/gpt4-pdf-chatbot-langchain Encountering an error when running the npm run ingest command: Error [Error: PineconeClient: Error calling upsert: Error: Pinecon ...

What could be causing the disappearance of my Angular 6 Service object variable upon refreshing the component it's injected into?

Recently, I encountered an issue with a SERVICE named test.service, which contains an object: public locationObject = { ...... ...... currency: string } In my project, this SERVICE is injected into the HeaderComponent and the object locationObj ...

I prefer not to permit components to receive undefined values

When using swr, the data type is IAge| undefined. I want to avoid passing undefined to AgeComponent, so I need the age type to be strictly IAge. Since AgeComponent does not allow undefined values, I am facing an error stating that 'IAge | undefined&ap ...

Compiling TypeScript code with Electron

Every time I attempt to compile a TypeScript Electron project sample, I encounter the issue 'chrome' does not exist on type ProcessVersions. Despite the Electron website suggesting that including the Electron node_module should provide TypeScript ...

Function type guards in Typescript do not support type inference

When checking for null in alpha, I validate the result and use throw new Error if needed. However, even after doing so, the compiler still indicates a compilation error: const obj = { objMethod: function (): string | null { return 'always a str ...

What is the best way for me to access a certain web address?

I am working on setting up a routing mechanism in my Angular project, but I'm encountering a URL routing error. The application is unable to locate the specified URL. Below is the routing setup: navigation.ts { id: 'documentation-manag ...

Is it possible to retrieve the distinct errors detected by ESLint?

I'm currently in the process of refactoring a project using TypeScript and React. After adding ESLint, I found over 300 errors scattered throughout the codebase. Facing such a significant number of errors, it's clear that these can't all be ...

What is the best way to retrieve all of the nearest directives and components in Angular?

Reviewing: <div class="widget-content"> <div class="widget-content"> <div> <widget-item></widget-item> </div> </div> </div> I am able to locate the clos ...

I'm perplexed as to why my array remains empty despite assigning a value to it in my controller. (Just to clarify, I am working with AngularJS, not Angular)

I spent a whole day debugging this issue without any luck. Issue: this.gridOptions.data = this.allTemplatesFromClassificationRepo ; **this.allTemplatesFromClassificationRepo ** remains an empty array. I have already called the activate() function to assig ...

Creating a class in TypeScript involves declaring a method that takes a parameter of type string, which matches the property name of a specific derived class type

I am working on a scenario where I have a base class containing a method that can be called from derived classes. In this method, you provide the name of a property from the derived class which must be of a specific type. The method then performs an operat ...

Is it possible to simulate or replace a static namespace function call when using Jasmine with Ionic framework?

I am currently navigating through new territory, so I appreciate your patience. My current project involves Ionic 2 using Angular 2, Typescript, and Jasmine for unit testing. At this moment, I am faced with the challenge of writing a unit test for a unique ...