Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Vue.js how to you flush a method that is debounced with lodash?

The Vue.js docs suggest using lodash's debounce function to debounce expensive methods, which I have successfully implemented. But occaisionally I don't want to act immediately, and lodash's docs say:

The debounced function comes with a cancel method to cancel delayed func invocations and a flush method to immediately invoke them.

But that is it. No information how to invoke the flush method. I found this blog post, but I am not sure how to implement that in a Vue.js component.

This is what I have in my Vue.js component at the moment (codepen):

<template>
  <input type='text' @keyup="change" @keyup.enter="changeNow">
</template>

<script>
export default {
  name: "MyComponent",
  methods: {
    change: _.debounce(function() {
      console.log("changing...");
    }, 250),
    changeNow: function() {
      this.change();
      this.change.flush();
    }
  }
};
</script>

change is properly debounced and only run once after typing, as expected. However, changeNow throws the following error:

Uncaught TypeError: this.change.flush is not a function

Any advice on how to implement this would be greatly appreciated!

like image 402
Ben Avatar asked Oct 25 '18 10:10

Ben


2 Answers

You are getting your issue because of a quirk in the way vue handles the methods section.

By default, Vue expects only Functions inside the methods list, and then it loops through those methods and calls .bind on them to make sure this always works.

Because this looping, you can only access the function itself, and no other members those functions have.

If you add the change method to your data section, you can access its properties and call the flush method:

var app = new Vue({
    el: "#app",    
      data: {
            change: _.debounce(function() {
        console.log("changing...");
      }.bind(this), 1000),
    },
    methods: {
      changeNow: function() {
        this.change.flush();
      }
    }
  });

https://codepen.io/anon/pen/gBZrrj?editors=1111

like image 91
Ferrybig Avatar answered Sep 19 '22 00:09

Ferrybig


This seems to work if you move your method definitions to the created hook as in the example in the docs ..

var app = new Vue({
    el: "#app",
    created() {
      this.change = _.debounce(function() {
        console.log("changing...");
      }, 1000);
      this.changeNow = function() {
        console.log("now...")
        this.change();
        this.change.flush();
      };
    }
  });

Codepen

like image 23
Husam Ibrahim Avatar answered Sep 22 '22 00:09

Husam Ibrahim