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);
}
}
}









share|improve this question


















  • 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










  • 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















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);
}
}
}









share|improve this question


















  • 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










  • 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













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);
}
}
}









share|improve this question













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






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 5 at 22:47









slanden

154114




154114








  • 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










  • 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














  • 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










  • 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








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












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)






share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














     

    draft saved


    draft discarded


















    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

























    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)






    share|improve this answer



























      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)






      share|improve this answer

























        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)






        share|improve this answer














        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)







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 8 at 6:42

























        answered Nov 7 at 19:19









        Vivick

        1,1951317




        1,1951317






























             

            draft saved


            draft discarded



















































             


            draft saved


            draft discarded














            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





















































            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







            這個網誌中的熱門文章

            Xamarin.form Move up view when keyboard appear

            Post-Redirect-Get with Spring WebFlux and Thymeleaf

            Anylogic : not able to use stopDelay()