Lodash's _.debounce() not working in Vue.js

Viewed 14670

I am trying to run a method called query() when a component property called q in Vue.js is modified.

This fails because this.query() is undefined. This is referring to my component's instance but somehow does not contain the methods.

Here's the relevant code part where I'm trying to watch the component property q and run the query() function:

methods: {
  async query() {
    const url = `https://example.com`;
    const results = await axios({
      url,
      method: 'GET',
    });
    this.results = results.items;
  },
  debouncedQuery: _.debounce(() => { this.query(); }, 300),
},
watch: {
  q() {
    this.debouncedQuery();
  },
},

Error:

TypeError: _this2.query is not a function

If I write the debounce() call as below, the TypeError: expected a function error appears even earlier, at the page load.

debouncedQuery: _.debounce(this.query, 300),
2 Answers

The issue comes from the lexical scope of the arrow function you define within _.debounce. this is bound to the object you are defining it in, not the instantiated Vue instance.

If you switch out your arrow function for a regular function the scope is bound correctly:

methods: {
  // ...
  debouncedQuery: _.debounce(function () { this.query(); }, 300)
}

We can do it by plain JS (ES6) with few lines of code:

function update() {

    if(typeof window.LIT !== 'undefined') {
        clearTimeout(window.LIT);
    }

    window.LIT = setTimeout(() => {
        // do something...
    }, 1000);

}
Related