3

I am trying to pass a Vue function to the lodash throttle method. Shouldn't I just be able to do something like this?

When I am trying to do this I am getting the following error:

Error in callback for watcher "query": "TypeError: Expected a function"

Watcher

watch: {
    query() {
        throttle(this.autocomplete(), 400);
    }
}

Methods

methods: {
    autocomplete() {}
}

Even though I am passing a function reference I am still getting an error message. If I wrap it with a anonymous function it won't fire:

throttle(() => { this.autocomplete(); }, 400);

I just checked and the autocomplete function does actually seem to fire regardless of the error that it is not a function in my example at the top.

What is going wrong here?

Edit:

Jsfiddle: http://jsfiddle.net/yMv7y/2780/

1
  • As @str said, this.autocomplete will return undefined. To get reference you can do this.$options.methods.autocomplete. not sure if its recommended. but even after doing that, it did not call autocomplete method. even after passing a function, throttle did not work. see the example here. There is also alternate solution in the fiddle. Commented Jun 7, 2017 at 9:23

3 Answers 3

5

You are passing the return value of this.autocomplete() (maybe undefined) and not the function reference. If you want to do the latter, you have to omit the brackets:

watch: {
    query() {
        throttle(this.autocomplete, 400);
    }
}
Sign up to request clarification or add additional context in comments.

4 Comments

I have tried this but nothing happens at all, my autcomplete won't fire. Not even something like a console.log.
@Stephan-v Maybe you should add more code. What is throttle?
Throttle is the lodash function which I imported: lodash.com/docs/4.17.4#throttle
This is creating a throttled function every time query changes. You want to constantly call the same throttled function like the answer below.
3

Working approach:

var demo = new Vue({
  el: '#demo',
  data: {
    query: ''
  },
  watch: {
    query: function() {
      this.autocomplete()
    }
  },
  methods: {
    autocomplete: _.throttle(function() {
      console.log('test');
    }, 50)
  }
})
<script src="http://vuejs.org/js/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>

<div id="demo" v-cloak>
    <input type="text" v-model="query">
</div>

As @Bill Criswell commented,

This is creating a throttled function every time query changes. You want to constantly call the same throttled function like the answer below.

Comments

2

My guess is that you need to define the throttled function with a non-invoked callback in a variable, and then invoke that as a function:

var throttled = throttle(this.autocomplete, 400)
watch: {
    query() {
        throttled();
    }
}

Just spent quite awhile trying to figure that one out...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.