Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

cannot bind event to object method

I have a vue single file component, which have a custom class instance as property: now i want to bind a event to a method of this class instance but i'm having issues, there is a simplified version of my code files

VueJS single file component

    <template>
        <div @click="class_prop.method"></div>
    </template>

    export default {
      data() {
        return {
            class_prop: new CustomClass(),
        };
      },
    }

CustomClass

    class CustomClass {
        constructor(){
            this.prop = 'default_value';
        }

        method(){
            this.prop = 'new_value';
            console.log(this.prop);
        }
    }

The error

When clicking on the page element i receive this error:

[Vue warn]: Error in v-on handler: "TypeError: Cannot read property 'prop' of null"

But when i try to call the custom class method from the browser console (i'm using Chrome with Vue Devtools extension) i get NO error, it works correctly:

$vm0.class_prop.method()

Since i get two different behaviours of my code i cannot tell if it is my class wrong, the vue single file component, or something else.

like image 403
fudo Avatar asked Mar 11 '26 07:03

fudo


2 Answers

Behind the scenes Vue somehow called or applied your method using null. Thus the error you've mentioned:

Error in v-on handler: "TypeError: Cannot read property 'prop' of null"


What can you do to workaround the problem?

You can use a lambda expression, so you can have full control of the object owner of the method, like this:

<div @click="() => class_prop.method()"></div>

You can also use the class instance in a method like this:

export default {
  data: () => ({
    foo: new CustomClass(),
  }),
  methods: {
    bar() {
      this.foo.method();
    },
  },
}

And then in your template:

<div @click="bar">{{ foo.prop }}</div>
like image 55
Washington Guedes Avatar answered Mar 12 '26 21:03

Washington Guedes


What you see is not Vue's fault, it's just plain JavaScript.

Here is a citation from great JS learning resource

The consequences of unbound this

If you come from another programming language, then you are probably used to the idea of a "bound this", where methods defined in an object always have this referencing that object. In JavaScript this is “free”, its value is evaluated at call-time and does not depend on where the method was declared, but rather on what object is “before the dot”.

Here is very simple example of consequences of above paragraphs (and why your code does not work):

class CustomClass {
  constructor() {
    this.prop = 'default_value';
  }

  method() {
    this.prop = 'new_value';
    console.log(this.prop);
  }
}

let instance = new CustomClass()

instance.method() // this works OK

let f = instance.method

f() // this does not! f is "unbound" ....have no "this"
like image 44
Michal Levý Avatar answered Mar 12 '26 23:03

Michal Levý



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!