I'm using React 18, Ionic 7, Formik 2.4 and Yup 0.32. I have an object with a nested object
export type Person = {
name: string
address: Address
}
The address objecdt is defined as
export type Address = {
city: string
}
export default Address
My Yup schemas are defined similarly
export const personValidationSchema = Yup.object({
name: Yup.string().required('First Name is required'),
address: addressValidationSchema
})
The address schema is defined as
export const addressValidationSchema = Yup.object({
city: Yup.string().required('City is required')
})
I'm not sure how to set up my error display logic to display an error if someone doesn't fill in a city in their Formik form. I have this
<IonInput
aria-label='City'
placeholder='City'
value={formikProps.values.address.city}
onIonChange={(e) => formikProps.setFieldValue('address.city', e.detail.value)}
name='address.city'
/>
{formikProps.touched.address.city && formikProps.errors.address.city ? (
<IonNote slot='error'>{formikProps.errors.address.city}</IonNote>
) : null}
The error if no name is entered displays just fine ...
<IonInput
aria-label='Name'
placeholder='Name'
value={formikProps.values.name}
onIonChange={(e) => formikProps.setFieldValue('name', e.detail.value)}
name='name'
/>
{formikProps.touched.name && formikProps.errors.name ? (
<IonNote slot='error'>{formikProps.errors.name}</IonNote>
) : null}
What else do I need to do? The example of this not working can be found here -- https://stackblitz.com/edit/an5yjh-v3s4ke?file=src%2Fschemas%2Faddress-schema.ts,src%2Fcomponents%2FMyForm.tsx,src%2Fschemas%2Fperson-schema.ts,src%2FApp.tsx
I took a look at the stackblitz example you posted and the bug I found was in MyForm
component. initialFormValues
had a typo in the spelling of city
const initialFormValues: Person = {
name: '',
address: {
ity: '', // this is the typo
},
};
this would be the correct fix
const initialFormValues: Person = {
name: '',
address: {
city: '', // this is the fix
},
};
Here's the complete component fix
import React, { useEffect, useRef, useState } from 'react';
import {
IonList,
IonItem,
IonLabel,
IonCheckbox,
IonIcon,
IonPage,
IonContent,
IonNote,
IonButton,
IonInput,
} from '@ionic/react';
import { pencilOutline } from 'ionicons/icons';
import Person from './types/person.type';
import { personValidationSchema } from '../schemas/person-schema';
import { Formik, FormikProps } from 'formik';
const MyForm: React.FC = () => {
const formikRef = useRef<FormikProps<Person>>(null);
const initialFormValues: Person = {
name: '',
address: {
city: '',
},
};
return (
<Formik
enableReinitialize={true}
innerRef={formikRef}
initialValues={initialFormValues}
validationSchema={personValidationSchema}
onSubmit={(values, { resetForm }) => {
alert('Saved!');
}}
>
{(formikProps) => (
<form onSubmit={formikProps.handleSubmit}>
<IonInput
aria-label="Name"
placeholder="Name"
value={formikProps.values.name}
onIonChange={(e) =>
formikProps.setFieldValue('name', e.detail.value)
}
name="name"
/>
{formikProps.touched.name && formikProps.errors.name ? (
<IonNote slot="error">{formikProps.errors.name}</IonNote>
) : null}
<IonInput
aria-label="City"
placeholder="City"
value={formikProps.values.address.city}
onIonChange={(e) =>
formikProps.setFieldValue('address.city', e.detail.value)
}
name="address.city"
/>
{formikProps.touched.address?.city &&
formikProps.errors.address?.city ? (
<IonNote slot="error">{formikProps.errors.address.city}</IonNote>
) : null}
<IonButton type="submit">Save</IonButton>
</form>
)}
</Formik>
);
};
export default MyForm;