Search code examples
javascriptvue.jslodashvuelidate

Vue.js vuelidate: How to debounce async custom validator?


I have a validator that checks if username is already registered in database. It worked fine, except for the fact, that the request was send to the server with each character entered - which is way to often. So i tried to debounce the setting of the username variable value but all i'm getting is this:

Uncaught TypeError: Cannot read property 'value' of undefined 
at a.NHnr.q.methods.debounceUsername.H.a.debounce.leading

Vue script:

import uniqueUsername from '../validation/uniqueUsername'
import _ from 'lodash'

export default {
    name: "signUpPage",
    data() {
      return {
        credentials: {
          username: ''
        }
      }
    },
    methods: {
      debounceUsername:
        _.debounce(function (e) {
          this.credentials.username = e.target.value;
        }, 200, {leading: false, trailing: true})
    },
    validations: {
      credentials: {
        username: {
          uniqueUsername: uniqueUsername
        }
      }
   }
}

Html:

    <b-field :label="msg('usernameLabel')"
             :class="{ 'form-group--error': $v.credentials.username.$error }">
      <b-input size="is-large" type="text" class="form__input"
               icon="account" name="username" v-on:input="debounceUsername" autofocus="">
      </b-input>
    </b-field> 
//b-field and b-input are from buefy library

Custom validator (uniqueUsername.js):

import axios from 'axios'

export default value => {
  if (value.trim().length === 0) return true;
  let usernameUnique;
  return new Promise(async function (resolve) {
    await axios('/isUsernameUnique', {
      method: "post",
      data: value,
      headers: {'Content-type': 'text/plain'}
    }).then((response) => usernameUnique = response.data);
    if (usernameUnique) resolve('username is unique');
  });
};

Solution

  • I found the answer. I had to change

    this.credentials.username = e.target.value;
    

    to:

    this.credentials.username = e;
    

    and it works now - frequency of sending requests is now max one every 200ms