vuejs3yupvee-validate

Vee-validate and yup with dynamic input fields not validating and showing errors


As a follow up question to my post here. I actually have fields in a loop so I need to setup vee-validate and yup dynamically.

So here's my script:

import { useForm } from 'vee-validate'
import * as yup from 'yup'

const {
  values,
  errors,
  defineComponentBinds,
  isSubmitting,
  setFieldValue,
  handleSubmit
} = useForm({
  validationSchema: yup.object({
    moduleValidationInputs: yup.object(moduleValidationSchemes.value)
  })
})

const moduleValidationSchemes = ref({})
const moduleValidationInputs = ref({})

onMounted(() => {
  newModuleFields.value.map(nmf => {
    if (nmf.rules && nmf.rules.required) {
      moduleValidationSchemes.value[nmf.uniqueName] = yup.string().label(nmf.label).required()
    } else moduleValidationSchemes.value[nmf.uniqueName] = yup.string().label(nmf.label).nullable()

    moduleValidationInputs.value[nmf.uniqueName] = defineComponentBinds(`moduleValidationInputs.${nmf.uniqueName}`)
  })
})

and my template:

<div v-for="(requiredField, rfx) in requiredFields" :key="rfx" class="col-6">
  <p>{{ errors }}</p>
  <span class="p-float-label">
    <InputText
     v-bind="moduleValidationInputs[requiredField.uniqueName]"
     class="w-full border-left-3 border-red-600"
    />
    <label>{{ requiredField.label }}</label>
  </span>
</div>

I just replicate the way the static fields I setup in the previous post, but I don't know why it's not showing any errors. It's like it's not validating the dynamic fields.

UPDATE:

I tested changing this line:

moduleValidationInputs: yup.object(moduleValidationSchemes.value)

Into this:

moduleValidationInputs: yup.object({
  lead_company: yup.string().label('Company').required()
})

And it works. .

It seems that useForm from vee-validate don't like generating dynamic yup.object to populate validationSchema.

Or am I doing it wrong?


Solution

  • Ended up using validateSync with setFieldError to handle error catching.

    const validateSyncFunc = handleSubmit((values, actions) => {
      // update errors
      Object.keys(moduleValidationInputs.value).forEach((key, index) => {
        const val = moduleValidationInputs.value[key].modelValue
        if (val !== null) setFieldError(key, null)
      })
    
      try {
        moduleValidationSchemes.value.validateSync(values, { abortEarly: false })
        return values
      } catch (error) {
        let errArray = []
        error.inner.map(err => {
          let obj = { [err.path]: err.message }
          errArray.push(obj)
          // actions.setErrors(obj)
          actions.setFieldError(err.path, err.message)
        })
    
        return error
      }
    })