I am using React Native with Expo, and am working in IOS currently.
Using Formik and Yup, I am trying to conditionally validate a form,
Here is the form.js
import {Formik} from 'formik'
import { newApptSchema } from '../FormValidation'
const NewAppt = ({ navigation }) => {
//These are the values that formik and yup will check
const apptForm = {
firstName: '',
lastName: '',
spouseFirstName: '',
spouseLastName: '',
etc...
}
const [hasSpouse, sethasSpouse] = useState(false);
return (
<Formik
//Prevents a dumb glitch
enableReinitialize
//validates based on the Form Validation Schema
validationSchema={newApptSchema}
initialValues={apptForm}
//Prevents Errors from popping up as they type
validateOnChange={false}
onSubmit={(values, actions)=>(
console.log(SubmitNewAppt()),
SubmitNewAppt(values),
navigation.navigate('Appointments')
)}
>
{(props)=> (
<>
<Text style={styles.lableText}>Do you have a Spouse?</Text>
<Switch
onValueChange={toggleSwitch}
value={hasSpouse}
/>
{ hasSpouse ? <>
<View style={{flexDirection:'row'}}>
<View style={{flex:1}}>
<TextInput
value={props.values.spouseFirstName}
placeholder='Spouse First Name'
onChangeText={props.handleChange('spouseFirstName')}/>
</View>
<View style={{flex:1}}>
<TextInput
value={props.values.spouseLastName}
placeholder='Spouse Last Name'
onChangeText={props.handleChange('spouseLastName')}>
</View>
</View>
{ props.errors.spouseFirstName || props.errors.spouseLastName ? <View style={{flexDirection:'row'}}>
<View style={{flex:1}}>
<Text style={styles.errorText}>Test</Text>
</View>
<View style={{flex:1}}>
<Text style={styles.errorText}>{ props.errors.spouseLastName }</Text>
</View>
</View> : null }
</>: null}
</>
)}
</Formik>
)
}
export default NewAppt
and here is my FormValidation.js
import * as Yup from 'yup'
//This file is used for all form validations across the app
//exporting the validation schemas to be used in formik forms across the app
export const newApptSchema = Yup.object({
hasSpouse: Yup.boolean(),
spouseFirstName: Yup.string()
.when("hasSpouse", {
is: true,
then: Yup.string()
.required("First Name is required")
.min(3, '3 Character Min')
}),
spouseLastName: Yup.string()
.when("hasSpouse", {
is: true,
then: Yup.string()
.required("Last Name is required")
.min(3, '3 Character Min')
}),
Phone2: Yup.string()
.when("hasSpouse", {
is: true,
then: Yup.string()
.matches('^((\\ [1-9]{1,4}[ \\-]*)|(\\([0-9]{2,3}\\)[ \\-]*)|([0-9]{2,4})[ \\-]*)*?[0-9]{3,4}?[ \\-]*[0-9]{3,4}?$', 'Phone number is not valid')
})
})
When "hasSpouse" is true, it should require spouseFirstName and spouseLastName, and validate Phone2, but for some reason it will go through without those even when hasSpouse has been toggled 'True'. It also will not throw the expected errors.
I've gone into the Yup git and NPM pages, but can't find the documentation for .when, I've only learned about it through Stack.
I assume I'm missing something dumb and somehow 'hasSpouse' is false in the validation schema, but I'm at a loss.
Any help would be greatly appreciated.
CodePudding user response:
Changing the Switch
value does not affect Formik's hasSpouse
value.
Refactor code as below
<Switch
onValueChange={(value) => {
props.setFieldValue("hasSpouse", value);
}}
value={props.values.hasSpouse}
/>;