1
votes

I have a problem with custom validation in vee-validate. I have this method, which is checking if email already exists in my database, but i'm keep getting error Error in callback for watcher "email": "TypeError: Cannot read property 'then' of undefined"

This is my HTML code, which has validation emailAlreadyExists

<div class="prepend-icon">
    <p :class="{ 'control': true }">
        <input v-validate="'required|email|emailAlreadyExists'"
               :class="{
                    'form-control input-lg': true,
                    'input': true,
                    'is-danger': errors.has('email')
                    }"
               name="email" type="email"
               v-bind:placeholder="$root.trans.translate('enterYourEmail')"
               v-model="email"
        />
        <i class="nc-icon-outline ui-1_email-83"></i>
        <span v-show="errors.has('email')" class="help-block with-errors">
                {{ errors.first('email') }}
            </span>
    </p>
</div>

And this is my validation inside created method

created() {
    this.$validator.extend('emailAlreadyExists', {
        getMessage: field => field + 'Email already exists.',
        validate: value => {
            let params = new URLSearchParams();
            params.append('email', value);
            this.$http.post(this.$apiUrl + `rest/api/public/User/checkIfUserExists`, params, {
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded',
                }
            })
        }
    })
}

And this is an error i'm keep getting in console log enter image description here

You can see whole file here: PasteBinLink

Can someone point what I'm doing wrong, that I'm keep getting this error? If you need any additional informations please let me know and i will provide. Thank you!

2
Could you add the whole Register component, please?user9246109
A have added paste bin link to whole fileValor_

2 Answers

4
votes

Your validate function is not returning anything. As per the examples in the document for custom validation:

validate(value) {
  return new Promise(resolve => {
    resolve({
      valid: value === 'trigger' ? false : !! value,
      data: value !== 'trigger' ? undefined : { message: 'Not this value' }
    });
  });
}

Notice the promise being returned.

See:

http://vee-validate.logaretm.com/rules.html#custom-rules

1
votes

Hmm the documentation is unclear, but i solved it this way:

app.js

new Vue({
    el: '#root',
    created() {
        this.$validator.extend('emailAlreadyExists',{
    getMessage: field => field + ' already exists.',
    validate: value => {
        return new Promise(resolve => {
            axios.get('/skills')
                .then(function (response) {
                    console.log(response.data[0]);
                    resolve({
                        valid: response.data[0],
                        data: value !== 'trigger' ? undefined : {message: 'Not this value'}
                    });
                })
                .catch(function (error) {
                    // handle error
                    console.log(error);
                })
                .then(function () {
                    // always executed
                });

        });
    }
});
    }
});

And html

 <input type="text" v-validate="'required|email|emailAlreadyExists'"  v-bind:class="[errors.first('email') ? 'registration_error' : '', 'form-control ']" name="email"/>

it seems like you have to register the validator in the created method