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');
});
};
One solution is to check when the user focused out of input field (blur) and then to run the async validations.So:
<input @blur="$v.username.$touch" v-model.lazy="username" />
The script:
export default {
data () {
return {
username: ''
}
},
validations: {
username: {
required,
isUnique(username) {
if (username === '') return true
return axios.get('/checkUsername')
.then(res => {
return res.data //res.data has to return true or false after checking if the username exists in DB
})
}
}
}
}
Note: in order to work this code you have to import axios and required from vuelidate
Also keep in mind.The backend has to return false if the username is unique in order the above code to work correctly
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With