BootstrapVue: Check database if username already exists: Optimal way to use debounce?

Viewed 180

Can I get a second set of eyes on using a <b-form-input> with debounce prop?

Use case: I am making an expensive API call to check if a username already exist in a database:

  <b-form-input
    id="username_input"
    v-model="formValues.username"
    type="text"
    debounce="500"
    @input="usernameCheck"
  ></b-form-input>

and here's the input handler usernameCheck:

async usernameCheck() {
  const username = this.formValues.username
  if (username.length >= 3 && username.length <= 15) {
    const ref = this.$fire.firestore.doc(`usernames/${username}`)
    const { exists } = await ref.get() // here I'm checking if document exists already
    this.usernameAvailable = !exists
  } else {
    ...
  }

Is this a good approach? Or should I be using a watcher?

1 Answers

I think there is a better way to approach this. First, the key point I discovered is that there is a difference between using @input and @update as mentioned here:

The input event is emitted on user update. You have to use the update event which is triggered to update the v-model to get your expected result.

So, I have now updated my code as follows (with some additional validation UX messaging):

<b-form-input
        id="username_input"
        v-model="formValues.username"
        type="text"
        debounce="500"
        :state="usernameValid"
        trim
        @update="usernameCheck"
      ></b-form-input>
      valid: {{ state }}
      <p v-show="formValues.username != '' && !usernameValid">
        Username must be between 3 and 15 characters
      </p>
      <p v-show="usernameAvailable && usernameValid">Username is available!</p>

import { BFormInput } from 'bootstrap-vue'
export default {
  components: {
    BFormInput
  },
  data() {
    return {
      formValues: {
        username: ''
      },
      usernameAvailable: false,
      state: null,
    }
  },
  computed: {
    usernameValid() {
      return (
        this.formValues.username.length >= 3 &&
        this.formValues.username.length <= 15
      )
    }
  },
  methods: {
    async usernameCheck() {
      const username = this.formValues.username
      if (this.usernameValid) {
        const ref = this.$fire.firestore.doc(`usernames/${username}`)
        const { exists } = await ref.get() // checks if doc exists in firebase db
        this.usernameAvailable = !exists
        this.state = true // input now in valid state
      } else {
        console.log('not a valid username')
        this.state = false
      }

So this works for me, but I have not done a full test. I do see that the network polling is reduced due to debounce, too.

I'd be curious if anyone has any ways I can improve this (if needed!). Thanks!

Related