Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot access this whilst debouncing search request in Vue with Lodash?

Tags:

lodash

vue.js

I have a simple search input:

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js" type="text/javascript"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.1.10/vue.js" type="text/javascript"></script>
<div id="app">
  <input type="text" v-model="search">
</div>

When you enter a value it will query a remote API to fetch and then display the data:

...
new Vue({
  el: '#app',
  data: {
    people: []
    search: ''
  },
  watch: {
    search() {
      // Rate limit
      this.debouncedSearch()
    }
  },
  methods: {
    debouncedSearch: _.debounce(() => {
      console.log(this)
      // self = this
      // io.socket.put('/search', this.search, (people, jwres) => {
      // self.people = people
      // })
    }, 500)
  },
  created(){
    this.people = locals.people
  }
})

The problem here is that console.log(this) returns undefined.

I have used this in another application and it works so battling to understand why not here.

Is there something that I have done wrong there, seems to be correct but no matter what I try I cannot access the scope of the Vue application in that debouncedSearch method?

like image 387
Craig van Tonder Avatar asked Feb 10 '17 22:02

Craig van Tonder


2 Answers

To solve the issue just replace the arrow function with function() {}

Replace this:

methods: {
    debouncedSearch: _.debounce(() => {
      console.log(this) // undefined
    }, 500)
  },

With This:

methods: {
    debouncedSearch: _.debounce(function () {
      console.log(this) // not undefined
    }, 500)
  },

Hope to help others took me a lot of time to figure it out.

like image 88
Abner Avatar answered Oct 01 '22 04:10

Abner


Pretty sure your problem is the use of the this-preserving function style. You need a way to refer to the Vue object you're creating (it's not this at the point your debounce function is defined). One way would be to do

const vm = new Vue({
  el: '#app',
  ...
  methods: {
    debouncedSearch: _.debounce(() => {
      console.log(vm)
      // io.socket.put('/search', vm.search, (people, jwres) => {
      // vm.people = response
      // })
    }, 500)
  },
like image 42
Roy J Avatar answered Oct 01 '22 05:10

Roy J