J.Ko
J.Ko

Reputation: 1052

Vue: passing `this.foo()` as event listener method

In my created() hook, I have the following code:

{
  created() {
    window.addEventListener('keydown', this.someMethod)
  }, 
  methods: {
    someMethod(event) {
      console.log(event)
      // do stuff
    }
  }
}

The console log is not firing. What am I doing wrong? The following works:

const someMethod = event => {
  console.log(event)
}

export default {
  ... other stuff
  created() {
    window.addEventListener('keydown', this.someMethod)
  },
}

EDIT: There seems to be some confusion about what I'm asking. I'm not asking how I can use this keyword inside the function. You use the arrow function for that. What I'm asking is I can't seem to pass the object's method as the callback function.

Upvotes: 2

Views: 1305

Answers (3)

Kamatchi
Kamatchi

Reputation: 1

{
  created() {
  let vm = this // could not use this keyword directly in eventlistener
  window.addEventListener('keydown', vm.someMethod)
  },
}

Upvotes: 0

Satyam Pathak
Satyam Pathak

Reputation: 6912

The catch is in the following code

created() {
    window.addEventListener('keydown', this.someMethod)
  },

someMethod is the fn and the object who is calling it refers to this.

Now whats the value of this here. The basic definition state about dynamic scope comes into play, dynamic scoped fn will have the value of this when the get called and not where they are written.

So when keydown occurs it's actually when things happened and works as per input which means - this is window and not the vue context.

To solve this issue we need to make that this to be lexical scoped which means value of this should be where the method is written.

ES6 Arrow is good option as mentioned in the first answer

created() {
  window.addEventListener('keydown', () => { 
    // Arrow method makes the value of `this` lexically scoped.
    // If you use normal fn , then again it get dynamically scoped
    this.someMethod()
  })
}

Upvotes: 1

Boussadjra Brahim
Boussadjra Brahim

Reputation: 1

You should set a callback as a second parameter to the addEventListener function and inside it call your method, it's recommended to use arrow function in order to access this in callback scope :

created() {
window.addEventListener('keydown',(e)=>{

    this.someMethod(e)

})
}

Upvotes: 2

Related Questions