Search code examples
javascriptvue.jsvuelidate

Validations in Vue using Vuelidate are not working


Hey guys

I wonder if I miss something here, iv'e trying to figure it out for a few hours and didn't came up with a solution.

I'm trying to use form validations using Vuelidate in vue, everything seems in place but after the custom alert I created, the form is still proceeding to the next stage.

I declared Vuelidate like this:

import useVuelidate from '@vuelidate/core'
import { required } from '@vuelidate/validators'

Inside Data() I did as follows:

data: () => ({
    v$: useVuelidate(),
    currentStage: 1,
    traffic: {
      unique: '',
      unique1: '',
      unique2: '',
      unique3: '',
      unique4: ''
    },
  }),

Declared validations outside of data(), like this:

validations() {
    return {
      traffic: {
        unique1: { required },
        unique2: { required },
        unique3: { required },
        unique4: { required },
        unique5: { required }
      },
    }
  },

Last thing is the computed, which I have function that is creating the input fields in stage 3 of the form:

  computed: {

        appendFields() {
          this.v$.$validate()
          if(!this.v$.$error){
            if(this.jsonStatham.hasOwnProperty(this.traffic.unique1)){
              this.integrationParams.push(...Object.keys(this.jsonStatham[this.traffic.unique1]))
            }
          } else {
            alert("Error, Not all fields are filled in.")
          }
        }
      },

So here is the problem, when appendFields() called, I do get this alert: alert("Error, Not all fields are filled in.") But After I press "ok" in the alert, the form is still proceeding to the next stage. What am I missing?

Edit: This is the button who execute the "appendFields" method:

<button @click="buttonClicked(0); appendFields;">Next Stage</button>

And this is buttonClicked function:

 buttonClicked(value) {
      if(value === 0){
        this.currentStage++;
        return this.currentStage;
      }
      if(value === 1){
        this.currentStage--;
        return this.currentStage;
      }
    },

Solution

  • The click-handler updates currentStage without first validating the form. However, the validation occurs in appendFields, which is computed after buttonClicked(). The validation should be the first step, which can block the proceeding steps.

    I would refactor it like this:

    1. Make appendFields a component method, since it's not really a computed property (especially because it returns nothing).

    2. Move the currentStage update into its own function for clarity.

    3. Move the form validation from appendFields() to the button's click-handler.

    4. In the click-handler, call the functions created in step 1 and 2 if the form is valid.

    export default {
      methods: {
        // 1️⃣
        appendFields() {
          if (this.jsonStatham.hasOwnProperty(this.traffic.unique1)) { 
    this.integrationParams.push(...Object.keys(this.jsonStatham[this.traffic.unique1]))
          }
        },
        // 2️⃣
        updateStage(value) {
          if (value === 0) {
            this.currentStage++
          } else if (value === 1) {
            this.currentStage--
          }
        },
        buttonClicked(value) {
          // 3️⃣
          this.v$.$validate()
    
          if (!this.v$.$error) {
            // 4️⃣
            this.appendFields()
            this.updateStage(value)
    
          } else {
            alert("Error, Not all fields are filled in.")
          }
        }
      }
    }
    

    Also be aware that useValidate() is intended for the Composition API, so it should be called inside setup():

    export default {
      setup() {
        return {
          v$: useValidate()
        }
      }
    }