Vue.js: using a data object's method in inline event handler
up vote
0
down vote
favorite
I have a Vue(2.5+) component where I'm setting a data property to a new Foo
object. Using foo.bar()
in the click handler calls the method correctly, but throws Uncaught TypeError: cannot set property 'someVariable' of null
when trying to modify properties inside the Foo
class. Setting it up so that Foo
is an object literal instead of a class also does not resolve the error.
I suspect something weird is happening with this
, between the component and the class?
Vue component
import Foo from './foo.js'
export default {
template: `<div @click="foo.bar"></div>`,
data() {
return {
foo: new Foo()
}
},
created() {
console.log(foo); // foo is not null here
}
}
Foo class
export default class Foo
{
constructor()
{
this.someVariable = 0;
}
bar(e)
{
// modify this.someVariable
}
}
but if I change the vue component to reference the external method through it's own "methods" property, it works.
Vue component (working)
import Foo from './foo.js'
export default {
template: `<div @click="bar"></div>`,
data() {
return {
foo: new Foo()
}
},
methods: {
bar(e) {
this.foo.bar(e);
}
}
}
vuejs2
add a comment |
up vote
0
down vote
favorite
I have a Vue(2.5+) component where I'm setting a data property to a new Foo
object. Using foo.bar()
in the click handler calls the method correctly, but throws Uncaught TypeError: cannot set property 'someVariable' of null
when trying to modify properties inside the Foo
class. Setting it up so that Foo
is an object literal instead of a class also does not resolve the error.
I suspect something weird is happening with this
, between the component and the class?
Vue component
import Foo from './foo.js'
export default {
template: `<div @click="foo.bar"></div>`,
data() {
return {
foo: new Foo()
}
},
created() {
console.log(foo); // foo is not null here
}
}
Foo class
export default class Foo
{
constructor()
{
this.someVariable = 0;
}
bar(e)
{
// modify this.someVariable
}
}
but if I change the vue component to reference the external method through it's own "methods" property, it works.
Vue component (working)
import Foo from './foo.js'
export default {
template: `<div @click="bar"></div>`,
data() {
return {
foo: new Foo()
}
},
methods: {
bar(e) {
this.foo.bar(e);
}
}
}
vuejs2
1
foo.bar
is a function without any context attached to it, eitherbind
the context or delegate as shown in your question
– Vivick
Nov 5 at 22:51
Wouldn't the context be the component?
– slanden
Nov 6 at 0:07
Here what you intended to do wasfoo.bar.bind(foo)
.
– Vivick
Nov 6 at 10:30
Thank you. Will you please elaborate why this must be done and explain more of the context? If you post in the form of an answer, I could accept it.
– slanden
Nov 7 at 18:05
add a comment |
up vote
0
down vote
favorite
up vote
0
down vote
favorite
I have a Vue(2.5+) component where I'm setting a data property to a new Foo
object. Using foo.bar()
in the click handler calls the method correctly, but throws Uncaught TypeError: cannot set property 'someVariable' of null
when trying to modify properties inside the Foo
class. Setting it up so that Foo
is an object literal instead of a class also does not resolve the error.
I suspect something weird is happening with this
, between the component and the class?
Vue component
import Foo from './foo.js'
export default {
template: `<div @click="foo.bar"></div>`,
data() {
return {
foo: new Foo()
}
},
created() {
console.log(foo); // foo is not null here
}
}
Foo class
export default class Foo
{
constructor()
{
this.someVariable = 0;
}
bar(e)
{
// modify this.someVariable
}
}
but if I change the vue component to reference the external method through it's own "methods" property, it works.
Vue component (working)
import Foo from './foo.js'
export default {
template: `<div @click="bar"></div>`,
data() {
return {
foo: new Foo()
}
},
methods: {
bar(e) {
this.foo.bar(e);
}
}
}
vuejs2
I have a Vue(2.5+) component where I'm setting a data property to a new Foo
object. Using foo.bar()
in the click handler calls the method correctly, but throws Uncaught TypeError: cannot set property 'someVariable' of null
when trying to modify properties inside the Foo
class. Setting it up so that Foo
is an object literal instead of a class also does not resolve the error.
I suspect something weird is happening with this
, between the component and the class?
Vue component
import Foo from './foo.js'
export default {
template: `<div @click="foo.bar"></div>`,
data() {
return {
foo: new Foo()
}
},
created() {
console.log(foo); // foo is not null here
}
}
Foo class
export default class Foo
{
constructor()
{
this.someVariable = 0;
}
bar(e)
{
// modify this.someVariable
}
}
but if I change the vue component to reference the external method through it's own "methods" property, it works.
Vue component (working)
import Foo from './foo.js'
export default {
template: `<div @click="bar"></div>`,
data() {
return {
foo: new Foo()
}
},
methods: {
bar(e) {
this.foo.bar(e);
}
}
}
vuejs2
vuejs2
asked Nov 5 at 22:47
slanden
154114
154114
1
foo.bar
is a function without any context attached to it, eitherbind
the context or delegate as shown in your question
– Vivick
Nov 5 at 22:51
Wouldn't the context be the component?
– slanden
Nov 6 at 0:07
Here what you intended to do wasfoo.bar.bind(foo)
.
– Vivick
Nov 6 at 10:30
Thank you. Will you please elaborate why this must be done and explain more of the context? If you post in the form of an answer, I could accept it.
– slanden
Nov 7 at 18:05
add a comment |
1
foo.bar
is a function without any context attached to it, eitherbind
the context or delegate as shown in your question
– Vivick
Nov 5 at 22:51
Wouldn't the context be the component?
– slanden
Nov 6 at 0:07
Here what you intended to do wasfoo.bar.bind(foo)
.
– Vivick
Nov 6 at 10:30
Thank you. Will you please elaborate why this must be done and explain more of the context? If you post in the form of an answer, I could accept it.
– slanden
Nov 7 at 18:05
1
1
foo.bar
is a function without any context attached to it, either bind
the context or delegate as shown in your question– Vivick
Nov 5 at 22:51
foo.bar
is a function without any context attached to it, either bind
the context or delegate as shown in your question– Vivick
Nov 5 at 22:51
Wouldn't the context be the component?
– slanden
Nov 6 at 0:07
Wouldn't the context be the component?
– slanden
Nov 6 at 0:07
Here what you intended to do was
foo.bar.bind(foo)
.– Vivick
Nov 6 at 10:30
Here what you intended to do was
foo.bar.bind(foo)
.– Vivick
Nov 6 at 10:30
Thank you. Will you please elaborate why this must be done and explain more of the context? If you post in the form of an answer, I could accept it.
– slanden
Nov 7 at 18:05
Thank you. Will you please elaborate why this must be done and explain more of the context? If you post in the form of an answer, I could accept it.
– slanden
Nov 7 at 18:05
add a comment |
1 Answer
1
active
oldest
votes
up vote
1
down vote
accepted
As said in the comments, foo.bar
without any context attached to it :
In JS functions are objects, just like any object they have their own this
"pointer".
In the evaluation of their body, this
is bound to a specific object referred to as context
which is either the default context (automatically set) or user defined (manually set).
Inheritance in JS is achieved through a prototype chain and methods should be defined on/attached to the class's prototype. Because of this, when you call foo.bar()
:
- You are in a method call context, therefore
foo
will be bound to the method
bar
is searched on the object first then in the prototype chain
But methods behave just like any other property : when you do foo.bar
you get a reference to the actual method which is an unbound function (default behavior for methods, since it is bound when called on an object).
Therefore, what you really need to do in this situation is foo.bar.bind(foo)
.
I would also suggest taking a quick look into this ES6 proposal for a bind operator and its implementation as a Babel plugin which allows nice things like passing ::foo.bar
instead of foo.bar.bind(foo)
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
accepted
As said in the comments, foo.bar
without any context attached to it :
In JS functions are objects, just like any object they have their own this
"pointer".
In the evaluation of their body, this
is bound to a specific object referred to as context
which is either the default context (automatically set) or user defined (manually set).
Inheritance in JS is achieved through a prototype chain and methods should be defined on/attached to the class's prototype. Because of this, when you call foo.bar()
:
- You are in a method call context, therefore
foo
will be bound to the method
bar
is searched on the object first then in the prototype chain
But methods behave just like any other property : when you do foo.bar
you get a reference to the actual method which is an unbound function (default behavior for methods, since it is bound when called on an object).
Therefore, what you really need to do in this situation is foo.bar.bind(foo)
.
I would also suggest taking a quick look into this ES6 proposal for a bind operator and its implementation as a Babel plugin which allows nice things like passing ::foo.bar
instead of foo.bar.bind(foo)
add a comment |
up vote
1
down vote
accepted
As said in the comments, foo.bar
without any context attached to it :
In JS functions are objects, just like any object they have their own this
"pointer".
In the evaluation of their body, this
is bound to a specific object referred to as context
which is either the default context (automatically set) or user defined (manually set).
Inheritance in JS is achieved through a prototype chain and methods should be defined on/attached to the class's prototype. Because of this, when you call foo.bar()
:
- You are in a method call context, therefore
foo
will be bound to the method
bar
is searched on the object first then in the prototype chain
But methods behave just like any other property : when you do foo.bar
you get a reference to the actual method which is an unbound function (default behavior for methods, since it is bound when called on an object).
Therefore, what you really need to do in this situation is foo.bar.bind(foo)
.
I would also suggest taking a quick look into this ES6 proposal for a bind operator and its implementation as a Babel plugin which allows nice things like passing ::foo.bar
instead of foo.bar.bind(foo)
add a comment |
up vote
1
down vote
accepted
up vote
1
down vote
accepted
As said in the comments, foo.bar
without any context attached to it :
In JS functions are objects, just like any object they have their own this
"pointer".
In the evaluation of their body, this
is bound to a specific object referred to as context
which is either the default context (automatically set) or user defined (manually set).
Inheritance in JS is achieved through a prototype chain and methods should be defined on/attached to the class's prototype. Because of this, when you call foo.bar()
:
- You are in a method call context, therefore
foo
will be bound to the method
bar
is searched on the object first then in the prototype chain
But methods behave just like any other property : when you do foo.bar
you get a reference to the actual method which is an unbound function (default behavior for methods, since it is bound when called on an object).
Therefore, what you really need to do in this situation is foo.bar.bind(foo)
.
I would also suggest taking a quick look into this ES6 proposal for a bind operator and its implementation as a Babel plugin which allows nice things like passing ::foo.bar
instead of foo.bar.bind(foo)
As said in the comments, foo.bar
without any context attached to it :
In JS functions are objects, just like any object they have their own this
"pointer".
In the evaluation of their body, this
is bound to a specific object referred to as context
which is either the default context (automatically set) or user defined (manually set).
Inheritance in JS is achieved through a prototype chain and methods should be defined on/attached to the class's prototype. Because of this, when you call foo.bar()
:
- You are in a method call context, therefore
foo
will be bound to the method
bar
is searched on the object first then in the prototype chain
But methods behave just like any other property : when you do foo.bar
you get a reference to the actual method which is an unbound function (default behavior for methods, since it is bound when called on an object).
Therefore, what you really need to do in this situation is foo.bar.bind(foo)
.
I would also suggest taking a quick look into this ES6 proposal for a bind operator and its implementation as a Babel plugin which allows nice things like passing ::foo.bar
instead of foo.bar.bind(foo)
edited Nov 8 at 6:42
answered Nov 7 at 19:19
Vivick
1,1951317
1,1951317
add a comment |
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53163385%2fvue-js-using-a-data-objects-method-in-inline-event-handler%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
foo.bar
is a function without any context attached to it, eitherbind
the context or delegate as shown in your question– Vivick
Nov 5 at 22:51
Wouldn't the context be the component?
– slanden
Nov 6 at 0:07
Here what you intended to do was
foo.bar.bind(foo)
.– Vivick
Nov 6 at 10:30
Thank you. Will you please elaborate why this must be done and explain more of the context? If you post in the form of an answer, I could accept it.
– slanden
Nov 7 at 18:05