Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

BarryJames's avatar

Vuelidate and @blur not working correctly.

Hey coders! I'm building a Vue front-end using a Laravel back-end and I seem to have run into a problems:

My @blur event runs properly on every property except for my custom validation 'unique' - which sends a GET request on every keystroke.

I have Googled for days without finding anything that mentions this and would really appreciate your help on this :)

Ok so take into consideration that I pass two props into this component with an array of users and a number containing the selected user's index in that array...

Here is my simplified script in my component for Edit User:

<script>
import { required, email, minLength } from 'vuelidate/lib/validators'
import axios from 'axios'
export default {
  data() {
    return {
      name: this.users[this.selectedUser].name,
      email: this.users[this.selectedUser].email
    }
  },
  props: {
    users: {
      type: Array,
      required: true
    },
    selectedUser: {
      type: Number,
      required: true
    }
  },
  validations: {
    name: {
      required,
      minLength: minLength(2)
    },
    email: {
      required,
      email,
      unique: value => {
        if (value === '') return true
        return axios.get('email-exists?email=' + value)
          .then(response => {
            return !response.data
          })
          .catch(error => {
            console.log(error)
          })
      }
    }
  },
  methods: {
    updateUser() {
      // axios request...
    }
  }
}

And here is my simplified HTML in my component in Edit User:

<template>
  <form @submit.prevent="updateUser">
    <div class="form-group">
      <label for="name">Name</label>
      <input type="text" id="name" class="form-control" :class="{'is-invalid': $v.name.$error}" @blur="$v.name.$touch()" v-model="name">
      <span v-if="!$v.name.error" class="invalid-feedback" role="alert">
        <strong v-if="!$v.name.minLength">Please enter a valid first name</strong>
        <strong v-if="!$v.name.required">Please enter your first name</strong>
      </span>
    </div>
    <div class="form-group">
      <label for="email">Email</label>
      <input type="email" id="email" class="form-control" :class="{'is-invalid': $v.email.$error}" @blur="$v.email.$touch()" v-model="email">
      <span v-if="!$v.email.error" class="invalid-feedback" role="alert">
        <strong v-if="!$v.email.email">Please enter a valid email address</strong>
        <strong v-if="!$v.email.unique">This email address already exists</strong>
      </span>
    </div>
    <button type="submit" class="btn btn-primary" :disabled="$v.$invalid">Update User</button>
  </form>
</template>

Thank you in advance! Maybe I am missing something here?

0 likes
6 replies
ouhare's avatar

Hello !

Did you try to wrap your axios call in a Promise and return it ?

BarryJames's avatar

Yep, just did that and still the same results.

      required,
      email,
      unique: function (value) {
        if (value === '') return true
        return new Promise((resolve, reject) => {

          return axiosGuest.get('users/' + this.users[this.selectedUser].id + '/email-exists-exc?email=' + value)
            .then(response => {
              if (response.data.email) {
                return true
              }
            })
            .catch(error => {
              if (error.response.data.error.email[0] == 'The email has already been taken.') {
                return false
              }
              return true
            })
        })
      },
    },
hollyit's avatar

You can't return out of a promise, you must resolve or reject. Change your return true/false to resolve(true/false).

1 like
ouhare's avatar

@barryjames yep, your promise have to be resolved or rejected !

......then(response => {
   if (response.data.email) {
      resolve(true)
   }
}.catch(error => {
   if (error.response.data.error.email[0] == 'The email has already been taken.') {
      resolve(false)
   } else {
      reject(error)
   }
}
BarryJames's avatar

Thanks guys! Although it didn't work..

Can I just find out - when you try something like this does it (@blur) function as expected? I mean using a custom unique validation?

I want to find out perhaps it's my browser or something...

Cheers!

BarryJames's avatar

After finding an article from 2017... I finally found the answer..

use v-model.lazy="data"

Should anyone run into the same problem. It seems Vuelidate doesn't handle @blur correctly when using an asynchronous validator.

Thanks!

2 likes

Please or to participate in this conversation.