thanks for reading this.
I am trying to build a form using Formik. And it includes a FieldArray inside a FieldArray.
For some reason, setFieldValue works as I can console.log the correct e.target.name and e.target.value
The problem is upon submitting the form, all the values from the inputs are not where they supposed to be. The expected behavior is the values should be inside of exclusionGroups, not outside.
Would anyone be able to give me some insight ? I've been stuck on this the whole day and feels like my head is going to explode.
Expected:
exclusionGroups: [
{
exclusion: [
{
param: 'delayMin',
operator: '<',
value: 'test1',
},
{
param: 'airlineCode',
operator: '>',
value: 'test2',
},
],
},
{
exclusion: [
{
param: 'flightNumber',
operator: '=',
value: 'test3',
},
],
},
],
Reality:
exclusionGroups: (2) [{…}, {…}]
group-1-operator-1: "<"
group-1-operator-2: ">"
group-1-param-1: "delayMin"
group-1-param-2: "airlineCode"
group-1-value-1: "test1"
group-1-value-2: "test2"
group-2-operator-1: "="
group-2-param-1: "flightNumber"
group-2-value-1: "test3"
My Code:
Index.tsx
type ExclusionRuleValues = {
param: string;
operator: string;
value: string;
};
interface ExclusionGroupProps {
exclusionRules?: ExclusionRuleValues[];
}
const Exclusion = ({ data, type }: any) => {
const onSubmit = (values: any) => {
console.log(values);
};
const initialValues = {
exclusionGroups: [
{
exclusion: [
{
param: 'group1',
operator: 'group1',
value: 'group1',
},
],
},
{
exclusion: [
{
param: 'group2',
operator: 'group2',
value: 'group2',
},
],
},
],
};
const emptyGroup = {
exclusion: [
{
param: '',
operator: '',
value: '',
},
],
};
return (
<React.Fragment>
<Formik
enableReinitialize
onSubmit={onSubmit}
initialValues={initialValues}
render={(formProps) => {
const { values, handleSubmit, submitForm } = formProps;
const { exclusionGroups } = values;
const setFieldValue = (e: ChangeEvent<HTMLInputElement>) => {
return formProps.setFieldValue(e.target.name, e.target.value);
};
return (
<React.Fragment>
<Header>
Model will return excluded message code if the following condition is true.
<Button onClick={submitForm} color="primary">
Save Changes
</Button>
</Header>
<Form onSubmit={handleSubmit}>
<FieldArray
name="exclusionGroups"
render={(arrayHelper) => (
<React.Fragment>
{exclusionGroups.map((exclusionRulesGroup: any, index: number) => {
return (
<TargetFields
type={type}
group={index + 1}
key={`field-${index}`}
name={`${arrayHelper.name}.${index}`}
setFieldValue={setFieldValue}
/>
);
})}
<AddNewGroupButton type="button" onClick={() => arrayHelper.push(emptyGroup)}>
+ New Group
</AddNewGroupButton>
</React.Fragment>
)}
/>
</Form>
</React.Fragment>
);
}}
/>{' '}
</React.Fragment>
);
};
export default Exclusion;
TargetFields.tsx
interface TargetFieldsProps {
group: number;
name: string;
type: string;
data?: ExclusionRuleValues[];
setFieldValue: (e: ChangeEvent<HTMLInputElement>) => void;
}
const TargetFields = ({ group, data, name, type, setFieldValue }: TargetFieldsProps) => {
const emptyTarget = {
param: '',
operator: '',
value: '',
};
return (
<React.Fragment>
<Field name={name}>
{(fieldProps: any) => (
<React.Fragment>
<ExclusionGroupHeader>
<b>Group {group}</b>
</ExclusionGroupHeader>
<Wrapper>
<FieldArray
name={`${fieldProps.field.name}.exclusion`}
key={`exclusion-${group}`}
render={(targetHelper) => (
<React.Fragment>
{fieldProps.field.value.exclusion.map(
(target: ExclusionRuleValues, key: number) => {
const { param, operator, value } = target;
return (
<ExclusionRuleGroup key={`group-${key}`}>
<ExclusionRuleHeader>
<b>Target {key + 1}</b>
<DeleteButton type="button" onClick={() => targetHelper.remove(key)}>
remove
</DeleteButton>
</ExclusionRuleHeader>
<StyledRow>
<CCol sm="4">
<Select
onChange={setFieldValue}
// value={param}
label="Params"
name={`group-${group}-param-${key + 1}`}
options={
type === 'input' ? InputExclusionParams : OutputExclusionParams
}
placeholder="Operator"
/>
</CCol>
<CCol sm="4">
<Select
onChange={setFieldValue}
// value={operator}
label="Operator"
name={`group-${group}-operator-${key + 1}`}
options={SelectOptions}
placeholder="Operator"
/>
</CCol>
<CCol sm="4">
<Input
onChange={setFieldValue}
// value={value}
label="Value"
name={`group-${group}-value-${key + 1}`}
type="text"
placeholder="Value"
/>
</CCol>
</StyledRow>
</ExclusionRuleGroup>
);
}
)}
<AddNewRuleButton type="button" onClick={() => targetHelper.push(emptyTarget)}>
+ New Rule
</AddNewRuleButton>
</React.Fragment>
)}
/>
</Wrapper>
</React.Fragment>
)}
</Field>
</React.Fragment>
);
};
export default TargetFields;