How to set validate rules in vuelidate to have value same as a field of an object?
Asked Answered
C

2

6

Let say I have a vue component with data like this:

  data: () => ({
    form: {
      old_password: {
        data: '',
        type: 'password',
        label: 'Old Password',
      },
      new_password: {
        data: '',
        type: 'password',
        label: 'New Password',
      },
      repeat_password: {
        data: '',
        type: 'password',
        label: 'New Password Confirmation',
      },
    },
  }),

The data is formatted in this way as I am using another plug-in, ant-design, to build the form, and therefore formatting the data in another way is not an option. The data field will be storing the actual data.

Then, I have the following validation rules set for vuelidate.

  validations: {
    form: {
      old_password: {
        data: { required },
      },
      new_password: {
        data: { required },
      },
      repeat_password: {
        data: { sameAsPassword: sameAs('new_password') },
      },
    },
  },

The required rules works, but the sameAsPassword rule is not working. It always return error, even I am sure I am inputting the same password. I guess it is not comparing to a correct field. How can I set the rule so that it is comparing to the correct field?

Cristophercristy answered 7/5, 2019 at 2:56 Comment(0)
M
7

new_password is not a sibling of repeat_password.data. From the built in validator docs

  • Locator can be either a sibling property name or a function. When provided as a function, it receives the model under validation as argument and this is bound to the component instance so you can access all its properties and methods, even in the scope of a nested validation.

So a function needs to be passed to sameAs:

validations: {
    form: {
      old_password: {
        data: { required },
      },
      new_password: {
        data: { required },
      },
      repeat_password: {
        data: { 
          sameAsPassword: sameAs(function() {
            return this.form.new_password.data;
          }) 
        },
      },
    },
  },

At the same time, for the this to be working inside the function, the data needed to be changed from arrow function to return data. i.e.

data() {
    return {
      form: {
        old_password: {
          data: '',
          type: 'password',
          label: 'Old Password',
        },
        new_password: {
          data: '',
          type: 'password',
          label: 'New Password',
        },
        repeat_password: {
          data: '',
          type: 'password',
          label: 'New Password Confirmation',
        },
      },
    }
  },
Mesencephalon answered 7/5, 2019 at 3:23 Comment(4)
Seems this is not the same inside the function, unable to get the variable in this way.Cristophercristy
Ops, after changing the data from arrow function to return, this seems to be working.Cristophercristy
with this solution i am getting this error: 'this' implicitly has type 'any' because it does not have a type annotation. do you have any suggestion for me? may be because i am using typescript class 'vue property decoratory'.Upholsterer
Not sure about typescript but perhaps this will helpMesencephalon
D
1

First of all: it's not a good idea to use arrow function for data. You should use:

data() {
 return {
   form: {}
 }
}

You could get a context issues..

And I don't know if you need that data inside validations...you could try this:

export default {
  data() {
    return {
      form: {
        nestedA: '',
        nestedB: ''
      }
    }
  },
  validations: {
    form: {
      nestedA: {
        required
      },
      nestedB: {
        required
      }
    }
  }
}
Dashboard answered 7/5, 2019 at 3:35 Comment(2)
Yes, I need the data inside validations. It is a data format required by ant-design for form.Cristophercristy
But a good point for changing the arrow function to return, that makes the answer of user2718281 perfect.Cristophercristy

© 2022 - 2024 — McMap. All rights reserved.