0
votes

TL:DR

In formik, if I have a field name written in dot notation (for instance name="hands.left") which is linked to a property of a nested object in initialValues (for instance hands: {left: " ", right: " "}), how can I use that field name when using validation errors, aka accessing object properties (errors.hands.left and errors["hands.left"] don't work)

As a consequence of my Typescript extended interface definitions, I have a dynamic Formik form with nested initialValues such as:

<Formik
  initialValues={{
    description: "",
    specialist: "",
    discharge: {
      date: "",
      criteria: "",
    },
// ...

The form fields attached to the nested values (discharge date and discharge criteria) is in the following shape:

          <Field
            name="discharge.date"
            component={TextField}
          />

I use dot notation as that seems to be the only way of linking the field with my initial values, so that when text is entered, the initialValue discharge.date (so, the date property of the discharge object in initialValues) is modified.

But my problem comes when adding Formik validation:

validate={(values) => {    
          const requiredError = "Field is required";
          const errors: { [field: string]: string } = {};   

          if (!values.discharge.date) {
            errors.discharge.date = requiredError;
          }
          // ...

If I try to access the error with dot notation like that (errors.discharge.date), I get a warning saying "Property 'date' does not exist on type 'string'".

My solution was to change the field name from "discharge.date" to "dischargeDate":

      <Field
        name="dischargeDate"
        component={TextField}
      />

and

      if (!values.discharge.date) {
        errors.dischargeDate = requiredError;
      }

Which does work for the error object, but disconnects the field from my initial value (discharge>date), so when I enter text in the field, instead of changing the state of the nested object value (discharge.date) a new separate variable "dischargeDate" is created:

enter image description here

What am I supposed to do when naming the field to access both the nested initialValue (initialValues>discharge>date) and the error object properties? (errors.discharge.date) Is the only solution to rename my Typescript types?

interface BaseEntry {
  description: string;
  specialist: string;
}

interface Discharge {
  date: string;
  criteria: string;
}

export interface HospitalEntryType extends BaseEntry {
  discharge: Discharge;
}
1

1 Answers

1
votes
import { FormikErrors } from 'formik';

interface BaseEntry {
  description: string;
  specialist: string;
}

interface Discharge {
  date: string;
  criteria: string;
}

export interface HospitalEntryType extends BaseEntry {
  discharge: Discharge;
}

interface FormValues extends HospitalEntryType {}

validate = (values: FormValues) => {
  let errors: FormikErrors<FormValues> = {};
  const requiredError = "Field is required";
  
  if (!values.discharge.date) {
    errors = { 
      discharge: {
        date: requiredError
      }
    }
  }

  return errors;
}