how to wait for user input in Vue 2

Viewed 865

I would like to wait for user input and as soon as the user stops typing do a search. I'm using a filter component that communicates with a data grid. As soon as the user finishes typing or selecting the options of a multiple select, the search (filtering) will be carried out.

I tried using the debounce from lodash but couldn't use it.

data() {
  nameOrCpfDebounce: ""
}

methods: {
    nameOrCpfDebounce: function() {
      this.nameOrCpfDebounce = debounce(
        value => (this.filters.nameOrCpf = value),
        3000
      );
    },
}
<TextField label="Nome ou CPF" @input="nameOrCpfDebounce" />

2 Answers

you can write a simple lazyCaller function like this:

Vue.config.productionTip = false;

new Vue({
  el: '#app',
  data: {
    timeout: null,
    inputValue: '',
  },
  methods: {
    lazyCaller(value, time = 500) {
      clearTimeout(this.timeout);
      this.timeout = setTimeout(() => {
        this.inputValue = value;
      }, time)
    }
  },
})
<script src="https://cdn.jsdelivr.net/npm/vue@2.x/dist/vue.js"></script>

<div id="app">
  <label for="name">input witth delay</label>
  <input :value="inputValue" type="text" name="name" @input="lazyCaller($event.target.value)">

  <div>
    <p>typed value will appear after 500ms:</p>
    <p>{{ inputValue }}</p>
  </div>
</div>

how it works is as follows:

  1. @input you pass the input's value to lazyCaller function
  2. in the function it first clears the last timeout by using the time out id saved in the timout variable in the data object so that the last timeout will not execute anymore
  3. then it stores a new time out id in the timeout variable, in the call back function of the setTimeout you can do whatever you want, in your case searching with the typed value but here I just update the inputValue in the data
  4. lazyCaller accepts a second argument to set for the timeout delay that I set it to 500ms for default so you can easily see the effect here but in your case I think a delay of 250 or 300 ms would be enough
  5. as long as the user keeps on typing nothing will happen because with each key input last timeout is cleared but if the user stops typing for 500ms (in my example), last timeout isn't cleared and gets executed

Can this help you?

If this doesn't work, please, give more details.

<template>
  <TextField
    label="Nome ou CPF"
    :value="value"
    @input="value => {
      nameOrCpf = value;
      myDebounce();
    }"
  />
</template>

<script>
const { debounce } = require("lodash");

export default {
  name: "FilterTable",
  data() {
    return {
      nameOrCpf: "",
      myDebounce: null
    };
  },
  created() {
    this.myDebounce = debounce(() => this.search(), 1000)
  },
  methods: {
    async search() {
      const response = await axios.get('...');
    }
  }
}
</script>

Have a nice day!

Related