0

I have a form that consists of cards where the user needs to select the derised ones. This form uses the useFormik hook and yup for validation. The code looks like so:

Declaration of formik in a form.tsx

export const validationSchema = object().shape({
  name: string().required(),
  networks_ids: array().min(1),
  players_ids: array().min(1),
})

export const useForm = () => {
  const formik = useFormik<IFormikValues>({
    initialValues: {
      name: '',
      networks_ids: [],
      players_ids: []
    },
    validationSchema,

Then the parent component looks like this (different file):

{networks?.map((wspace, index) => (
                <div key={index}>
                  <NetworkSelectCard
                    formik={formik}
                    name={`networks_ids[${index}]`}
                    network={wspace!}
                    value={wspace?._id}
                  />
                </div>
))}

Child component

const NetworkSelectCard: FC<NetworkSelectCardProps> = ({
  formik,
  name,
  network,
  value,
}) => {
  return (
    <SelectCardFormik {...{ formik, name, network, value }}>
         **Some JSX in here***
    </SelectCardFormik>

Another child component again in a different file

export const SelectCardFormik: FC<SelectCardFormikProps> = ({
  formik,
  ...props
}) => {
  const meta = formik?.getFieldMeta(props.name!)
  return (
    <SelectCard
      {...props}
      checked={meta?.value?.length > 0}
    />
  )
}

And finally:

const SelectCard: FC<SelectCardProps> = (props) => {
  const { type, value, disabled, name, children, checked, onChange } = props
  const inputRef = useRef<HTMLInputElement>(null)

  return (
***More out of context JSX in here***

        <input
          ref={inputRef}
          name={name}
          type={type || 'checkbox'}
          checked={checked}
          value={value}
          onChange={onChange}
          readOnly
       />

The problem now is that if console.log(formik.values) I see that it is doing this:

{
  "name": "My dope name",
  "networks_ids": [
    [
      "5f33eb0873c9ef232a58cf53"
    ],
    [
      "5f33eb0873c9ef232a58cf54"
    ]
  ],
  "players_ids": [],
// Should be and array of strings and not an array of arrays

I can't really understand how this is hapenning, maybe I'm missing something because it is the first time I'm working with formik. If no cards are selected the Next step button needs to be disabled. So I could also try to flatten the array on onSubmit but for that I need to adjust my schemaValidation, which I'm also having a hard time to understand how could I validate if an array is empty or it only has arrays inside of it that are empty to. Because when unselecting the card, it only removes the id inside of the array but keeps an empty array, like the following:

"networks_ids": [
    [],
    [
      "5f33eafa73c9ef232a58cf52"
    ]
  ],

I'm sorry for the LONG LONG question but I already waisted to much hours arounds this I can't find a solution anywhere. Thank you

PmmZenha
  • 155
  • 2
  • 9

1 Answers1

0

Its very tough to understand whatever you have explained. However if you want a solution to use your networks_ids then use

networks_ids.flat() // returns array of string
Anup
  • 589
  • 4
  • 8
  • I already tried the _.flatten from lodash, the issue is how can I flatten the array as soon as the network_ids get updated? I tried to do it on `onChange` how ever has expected the value it not yet updated when calling `setFielValue('networks_ids', flattenArray)` inside of `onChange` – PmmZenha Aug 17 '20 at 17:49
  • You can get use of spread operators while using the setFielValue Something Like this newNetworkId="abcd" ```setFielValue('networks_ids', [...flattenArray.flat() , [...[newNetworkId]]].flat())``` – Anup Aug 17 '20 at 17:57
  • I tried it but it doesnt work because it , I guess the best to do here is validate with yup if the array is empty and if all arrays inside of it are all empty to. And then flat the array inside onSubmit. I dont like this approach but might be the best one atm – PmmZenha Aug 17 '20 at 18:31