Why doesn't it work when sameAs is used in vuelidate?
Asked Answered
P

9

11

fieldName not found to vuelidate of sameAs method.

sameAs(blabla)

blabla = 'internalFormData.password', 'internalFormData.password.value', 'this.internalFormData.password', 'this.internalFormData.password.value', 'password', 'this.password', 'password.value'

-----------script----------
data () {
  return {
     internalFormData: {
        password: '',
        repassword: ''
      }
   }
},


validations: {
      password: {
        value: {
          required,
          minLength: minLength(8)
        }
      },
      repassword: {
        value: {
          required,
          minLength: minLength(8),
          sameAs: sameAs('internalFormData.password')
        }
      }
    }
  },



---------------template--------------
<error
   v-if="!$v.internalFormData.repassword.value.sameAs"
>
  비밀번호가 일치하지 않습니다.
<error>

The error won't go away.

Precatory answered 17/2, 2019 at 8:35 Comment(0)
N
17

Simple example with composition api:

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

const form = {
    email: '',
    confirm_email: '',
}
const rules = {
    email: { required, email },
    confirm_email: { required, sameAs(computed(()=> form.email))) },
}
const v$ = useVuelidate(rules, form)
Nates answered 14/12, 2022 at 10:11 Comment(0)
M
5

Your validations structure should mirror object(s) in data, thus it should be:

validations: {
  internalFormData: {
    password: {
      required,
      minLength: minLength(8)
    },
    repassword: {
      required,
      minLength: minLength(8),
      sameAs: sameAs('internalFormData.password')
    }
  }
}
Millsaps answered 17/2, 2019 at 10:15 Comment(2)
Replace sameAs: sameAs('internalFormData.password') with sameAs: sameAs(internalFormData.password) . I mean remove the quotesStamata
@DestinyMaina Won't work without quotes. It should be a name (in dot-notation) of a target field. Without quotes it will be undefined reference.Millsaps
L
4

You need to point out your nested attribute with a function. Like this :

data(){return {
 password :{
  new: '',
  newRepeated:''
 }
}},    
validations : {
 password: {
  new : {required},
  newRepeated : {
   required,
   sameAs : sameAs( function(){return this.password.new} )
  }
 }
}

I would also suggest you to take a look at this closed issue. https://github.com/vuelidate/vuelidate/issues/252

Linettelineup answered 13/3, 2020 at 14:36 Comment(0)
D
4

Example for vue3:

validations () {
    return {
        admin: { 
            type: {
                required
            },
            email: {
                required,
                email
            },
            password: { 
                required, 
                minLength: minLength(10) 
            },
            confirmPassword: { 
                required, 
                sameAs: sameAs(this.admin.password)
            }
        }
    }
}
Decommission answered 10/5, 2022 at 9:41 Comment(0)
S
1

Replace this line:

sameAs: sameAs('internalFormData.password')

With

sameAs: sameAs(this.internalFormData.password)

The parameter should not be a string but rather the actual attribute using 'this' I am not sure whether the validations not being identical to the data internalFormData will affect how it works bu I suggest you ensure they match to fit as shown below:

  validations: {
  internalFormData: {
    password: {
      required,
      minLength: minLength(8)
    },
    repassword: {
      required,
      minLength: minLength(8),
      sameAs: sameAs(this.internalFormData.password)
    }
  }
}
Stamata answered 10/8, 2022 at 17:21 Comment(0)
W
1

I found that the sameAs will only work if your validation obj is a function.

validations() {
  //your validations
}

instead of:

validations: {
  //your validations
}
Whisker answered 22/7, 2023 at 0:23 Comment(0)
G
0

try this solution :

<template>
       <div>
            <div>
                <label>Current Password:</label>
                <input type="password" v-model="updatePassword.CurrentPassword"/>
        
                <div v-if="updatePasswordValidate.CurrentPassword.$errors.length">
                    {{ updatePasswordValidate.CurrentPassword.$errors[0].$message }}
                </div>
            </div>
            <div class="mb-4">
                <label>New Password:</label>
                <input type="password" v-model="newPassword"/>
        
                <div v-if="updatePasswordValidate.NewPassword.$errors.length">
                    {{ updatePasswordValidate.NewPassword.$errors[0].$message }}
                </div>
            </div>
            <div>
                <label>Re-type New Password:</label>
           <input type="password" v-model="updatePasswordValidate.retypePassword.$model"/>
        
                <div v-if="updatePasswordValidate.retypePassword.$errors.length">
                    {{ updatePasswordValidate.retypePassword.$errors[0].$message }}
                </div>
            </div>

            <div>
                <button
                    id="updatePassBtn"
                    @click="updateUserPassword"
                    type="button">Change Password</button>
            </div>
        </div>
 </template>


<script>
import useVuelidate from "@vuelidate/core";
import {required, sameAs, minLength} from "@vuelidate/validators";
export default {
    data() {
        return {
            updatePasswordValidate: null,
            newPassword: "",
            updatePassword: {
                CurrentPassword: null,
                NewPassword: null,
            },
        };
    },
    components: {BaseAlert},
    watch: {
        newPassword(newV) {
            this.updatePassword.NewPassword = newV;
            this.loadValidation();
        },
    },
    computed: {
        rulesUpdatePassword() {
            return {
                CurrentPassword: {
                    required,
                    minLength: minLength(8),
                },
                NewPassword: {
                    required,
                    minLength: minLength(8),
                },
                retypePassword: {
                    required,
                    minLength: minLength(8),
                    sameAs: sameAs(this.updatePassword.NewPassword, "New Password"),
                },
            };
        },
    },
    props: {
        token: {
            required: true,
        },
    },
    methods: {
        updateUserPassword() {
          console.log('handle update button')   
        },
        loadValidation() {
            this.updatePasswordValidate = useVuelidate(
                this.rulesUpdatePassword,
                this.updatePassword
            );
        },
    },
    created() {
        this.loadValidation();
    },
};
</script>
Get answered 24/2, 2023 at 21:10 Comment(1)
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Urbain
C
0

For those struggling with the composition API. The simplest solution I found was to turn my rules object into a rules function that returned the same object. The values of the variables given to sameAs then stop being the one of the component creation and are reactive.

So, instead of

const rules = {...

use

const rules = () => ({...

See sultan's answer for the options API variation of this solution.

Craniometry answered 13/3 at 22:31 Comment(0)
S
-1

You must be use .value

sameAs: sameAs('internalFormData.value.password')
Sinistrodextral answered 16/12, 2022 at 10:29 Comment(1)
Instead of simply providing the answer directly, try writing a detailed comment that explains the solution, as long as the explanation is not too lengthy. @Hakan Özdemir .Tripterous

© 2022 - 2024 — McMap. All rights reserved.