4

I have a search module in which: when a user stop typing it should search the name.

What I think the solution is to do a timeout when a user keyup. reference

<input type="text" @keyup="textSearch($event)">

textSearch(e){
    var timer;
    clearTimeout(timer);

    timer = setTimeout(() => {
        alert('searching...');
    }, 2500);
}

The code were all working, the problem is why when I type 3 character in just 1 second it pops out 3 alerts? I expect there should be one pop-out since it waits for 2.5 seconds.

Is there something wrong with the code? Need help Sirs

charles
  • 364
  • 6
  • 18

4 Answers4

12

If I understand you problem correctly the timeout you clear each time you run textsearch()is not the one you last created, but the one you just declared with var timer. I'd suggest storing your timer variable in your data properties instead to have clearTimeout clear the right timeout.

Something like this:

data: {
    timer: undefined
},
methods: {
    textSearch(e){
      clearTimeout(this.timer)

      this.timer = setTimeout(() => {
          alert('searching...')
      }, 2500)
    }
}

Working fiddle of your code with my modifications:

https://jsfiddle.net/MapletoneMartin/yjxfsehz/2/

Good luck!

MartinSRimsbo
  • 196
  • 1
  • 4
3

Here is a solution:

setTimeout is fine -- alternatively, you can use debounce Vue-debounce

<input v-debounce:400ms="myFn" type="text" />

<script>
export default {
  methods: {
    myFn(val) {
      console.log(val) // => The value of the input
    }
  }
}
</script>
Hardik Raval
  • 3,406
  • 1
  • 26
  • 28
2

What I do to fix this issue is that I take timer variable in Vue data because when textSearch method called inside timer function is reassigned.

data () {
    return {
        timer: null
    }
}


textSearch(e){
    clearTimeout(this.timer);

    this.timer = setTimeout(() => {
        alert('searching...');
    }, 2500);
}

I think this will solve your issue.

Shahadat Hossain
  • 947
  • 9
  • 24
1

Another solution for this is, to use a watch instead of using event-keyup. You must create model first.

<input type="text" v-model="searchTxt">

data(){
    return{
        searchTxt: ''
    }
},

watch: {
    searchTxt: function(val) {
        if (!this.awaitingSearch) {
          setTimeout(() => {
            alert('searching');
            alert(this.searchTxt); //alert value

            this.awaitingSearch = false;
          }, 2500); // 2.5 sec delay
        }
        this.awaitingSearch = true;
    }
}

More information

tempra
  • 2,455
  • 1
  • 12
  • 27