I am using the debounce method from here https://www.freecodecamp.org/news/javascript-debounce-example/
function debounce(func, timeout = 300){
let timer;
return (...args) => {
clearTimeout(timer);
timer = setTimeout(() => { func.apply(this, args); }, timeout);
};
}
function saveInput(){
console.log('Saving data');
}
const processChange = debounce(() => saveInput());
and I want to include in a library we have, so in common.js I have:
export default {
otherStuff,
debounce(func, timeout = 300) {
let timer;
return (...args) => {
clearTimeout(timer);
timer = setTimeout(() => {
func.apply(this, args);
}, timeout);
};
},
in vue.js I have a textbox which has an event @keyup="searchboxChange()"
and in the methods section:
import common from "@/assets/js/Service/Common";
... stuff removed for brevity
methods:
{
searchboxChange(){
common.debounce(() => this.filterChanged(), 1000)();
},
}
I had to include () at the end of the debounce method else it didn't actually fire. However, while it debounces perfectly, when the timeout expires every event is then fired. So if my search was "HELLO" I would see 5 requests all fired at the same time as this.filterChanged() was called 5 times.
I am sure it is something simple with the scope of the timeout variable, because adding a console.log into the debounce method shows the timer is undefined each time.
You need to debounce the component method, otherwise you'll be invoking multiple debounced functions from within your component method.
Something like this should work
methods: {
// ...
searchboxChange: common.debounce(function() {
this.filterChanged();
}, 1000)
}
Notice the use of function as opposed to short function syntax. You'll need to do this to ensure the correct lexical scope of this
Firstly, as always, thanks to everyone who contributed a solution. However, none got past the "this" is not the right scope.
The solution was to set the function in created. (source: https://forum.vuejs.org/t/lodash-debounce-not-working-when-placed-inside-a-method/86334/4)
which (in case link goes dead) is effectively saying
move the part that you need to debounce into its own method and debounce that (like you did in the codepen for he first method).
Then you can call the debounced method from the event handler method.
It’s also better to debounce each instance method dynamically during created, otherwise component instances that the same debounced function and that can lead to wonky debounce behaviour:
and their code sample:
created() {
this.updateForm = _.debounce(this.updateForm, 500)
},
methods: {
triggerUpdate(event){
// perform some action before debouncing
this.updateForm(event)
} ,
updateForm: (event){
console.log('in update')
}
so for my case:
created() {
this.searchboxChange = common.debounce(this.filterChanged, 1000)
},
yes, that is literally it.
only one network call now.