2

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.

Boussadjra Brahim
  • 82,684
  • 19
  • 144
  • 164
J.Ko
  • 964
  • 12
  • 26
  • 1
    Possible duplicate of [How to access the correct \`this\` inside a callback?](https://stackoverflow.com/questions/20279484/how-to-access-the-correct-this-inside-a-callback) – Jared Smith Aug 26 '19 at 19:14
  • 2
    @JaredSmith I don't think so, the OP isn't using `this` in the method. (And doesn't Vue even autobind them iirc?). He's complaining that the method doesn't run at all, not that `// do stuff` (which might use `this`) doesn't work. – Bergi Aug 26 '19 at 19:26
  • @Bergi retracted, good catch – Jared Smith Aug 26 '19 at 19:28
  • The initial code works in an empty project. I suspect something else is going on. Are there any [event modifiers](https://vuejs.org/v2/guide/events.html#Event-Modifiers) in your project like `stop`? – David Weldon Aug 26 '19 at 19:53
  • @DavidWeldon I do have event modifiers, but they're attached to inputs and other HTML elements, not `window`, so I don't see how that'd cause this to happen. – J.Ko Aug 27 '19 at 05:11
  • It would, but only if they were focused. I'd recommend debugging this by removing components until it works, or by starting with an empty project and adding components until it breaks. – David Weldon Aug 27 '19 at 05:14

3 Answers3

2

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)

})
}
Boussadjra Brahim
  • 82,684
  • 19
  • 144
  • 164
1

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()
  })
}
Satyam Pathak
  • 6,612
  • 3
  • 25
  • 52
0
{
  created() {
  let vm = this // could not use this keyword directly in eventlistener
  window.addEventListener('keydown', vm.someMethod)
  },
}
  • Welcome to SO! Please take a look at the other answers that were given before. Your approach is mentioned there already. In order to keep the site clear and make it easy to find answers, we try to avoid double answers. – ahuemmer Dec 19 '22 at 07:55