Cannot use 'this' keyword in an object because it is inside another function












4















I am using vue.js in this case but I guess it would apply in plain JS too. The problem is that when I am in a function that is in another function I am having to call variables by their full path like - Object.variable instead of this.variable. Is there a way to use this.timer, this.pages instead of TVComponent.pages etc.



const TVComponent = new Vue ({
el: '.tvContent',

data:
{
current_page: 0,
timer: 0,
pages: [
{ page: '/', interval: 10 },
{ page: 'tv/calls', interval: 10 },
{ page: 'tv/general', interval: 10 }
]
},

methods:
{
tvTimer()
{
setInterval(function() {
TVComponent.timer++;

if (TVComponent.timer == TVComponent.pages[TVComponent.current_page].interval) {
console.log('it is time!!');
}

console.log(TVComponent.pages[TVComponent.current_page].page);
}, 1000);
},
})









share|improve this question



























    4















    I am using vue.js in this case but I guess it would apply in plain JS too. The problem is that when I am in a function that is in another function I am having to call variables by their full path like - Object.variable instead of this.variable. Is there a way to use this.timer, this.pages instead of TVComponent.pages etc.



    const TVComponent = new Vue ({
    el: '.tvContent',

    data:
    {
    current_page: 0,
    timer: 0,
    pages: [
    { page: '/', interval: 10 },
    { page: 'tv/calls', interval: 10 },
    { page: 'tv/general', interval: 10 }
    ]
    },

    methods:
    {
    tvTimer()
    {
    setInterval(function() {
    TVComponent.timer++;

    if (TVComponent.timer == TVComponent.pages[TVComponent.current_page].interval) {
    console.log('it is time!!');
    }

    console.log(TVComponent.pages[TVComponent.current_page].page);
    }, 1000);
    },
    })









    share|improve this question

























      4












      4








      4








      I am using vue.js in this case but I guess it would apply in plain JS too. The problem is that when I am in a function that is in another function I am having to call variables by their full path like - Object.variable instead of this.variable. Is there a way to use this.timer, this.pages instead of TVComponent.pages etc.



      const TVComponent = new Vue ({
      el: '.tvContent',

      data:
      {
      current_page: 0,
      timer: 0,
      pages: [
      { page: '/', interval: 10 },
      { page: 'tv/calls', interval: 10 },
      { page: 'tv/general', interval: 10 }
      ]
      },

      methods:
      {
      tvTimer()
      {
      setInterval(function() {
      TVComponent.timer++;

      if (TVComponent.timer == TVComponent.pages[TVComponent.current_page].interval) {
      console.log('it is time!!');
      }

      console.log(TVComponent.pages[TVComponent.current_page].page);
      }, 1000);
      },
      })









      share|improve this question














      I am using vue.js in this case but I guess it would apply in plain JS too. The problem is that when I am in a function that is in another function I am having to call variables by their full path like - Object.variable instead of this.variable. Is there a way to use this.timer, this.pages instead of TVComponent.pages etc.



      const TVComponent = new Vue ({
      el: '.tvContent',

      data:
      {
      current_page: 0,
      timer: 0,
      pages: [
      { page: '/', interval: 10 },
      { page: 'tv/calls', interval: 10 },
      { page: 'tv/general', interval: 10 }
      ]
      },

      methods:
      {
      tvTimer()
      {
      setInterval(function() {
      TVComponent.timer++;

      if (TVComponent.timer == TVComponent.pages[TVComponent.current_page].interval) {
      console.log('it is time!!');
      }

      console.log(TVComponent.pages[TVComponent.current_page].page);
      }, 1000);
      },
      })






      javascript vue.js






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Jan 2 at 10:42









      LigaLiga

      304111




      304111
























          4 Answers
          4






          active

          oldest

          votes


















          2














          Classic problem of this being not what you expect in a function



          A. bind it



          methods:
          {
          tvTimer()
          {
          setInterval(function() {
          // ...
          }.bind(this), 1000);
          },
          })


          B. use a closure



          methods:
          {
          tvTimer()
          const _this = this
          {
          setInterval(function() {
          _this.timer ...
          }, 1000);
          },
          })


          C. use an arrow function



          methods:
          {
          tvTimer()
          {
          setInterval(() => {
          this.timer ...
          }, 1000);
          },
          })


          This is one of those things one has to really understand about JS in order to not fall for it over and over in different places. I suggest this ebook:



          https://github.com/getify/You-Dont-Know-JS/blob/master/up%20%26%20going/ch2.md#this-identifier






          share|improve this answer
























          • Thanks, I did not know about binding and arrow functions. Will need to read up on it!

            – Liga
            Jan 2 at 10:51



















          1














          The function you pass to setInterval receives its own context, however if you use an arrow function it will use the current context instead, and ignore the one given by setInterval.



          setInterval(() => { ... }, 1000)





          share|improve this answer































            0














            This is because setInterval() this object is not same as vue.js this, since they have different scopes.



            Try to assign this object to new variable before entering the problematic function's scope.



            let self = this;
            tvTimer()
            {
            setInterval(function() {
            self.timer++;

            if (self.timer == self.pages[self.current_page].interval) {
            console.log('it is time!!');
            }

            console.log(self.pages[self.current_page].page);
            }, 1000);
            },


            See: https://developer.mozilla.org/en-US/docs/Glossary/Scope






            share|improve this answer































              -1














              I think you have to bind it in this context. We do it this way in React classess.






              share|improve this answer
























              • how do you bind it?

                – Liga
                Jan 2 at 10:44











              • You can use data.timer that is a better way

                – Shakeel Ahmed
                Jan 2 at 10:49











              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',
              autoActivateHeartbeat: false,
              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%2f54004882%2fcannot-use-this-keyword-in-an-object-because-it-is-inside-another-function%23new-answer', 'question_page');
              }
              );

              Post as a guest















              Required, but never shown

























              4 Answers
              4






              active

              oldest

              votes








              4 Answers
              4






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes









              2














              Classic problem of this being not what you expect in a function



              A. bind it



              methods:
              {
              tvTimer()
              {
              setInterval(function() {
              // ...
              }.bind(this), 1000);
              },
              })


              B. use a closure



              methods:
              {
              tvTimer()
              const _this = this
              {
              setInterval(function() {
              _this.timer ...
              }, 1000);
              },
              })


              C. use an arrow function



              methods:
              {
              tvTimer()
              {
              setInterval(() => {
              this.timer ...
              }, 1000);
              },
              })


              This is one of those things one has to really understand about JS in order to not fall for it over and over in different places. I suggest this ebook:



              https://github.com/getify/You-Dont-Know-JS/blob/master/up%20%26%20going/ch2.md#this-identifier






              share|improve this answer
























              • Thanks, I did not know about binding and arrow functions. Will need to read up on it!

                – Liga
                Jan 2 at 10:51
















              2














              Classic problem of this being not what you expect in a function



              A. bind it



              methods:
              {
              tvTimer()
              {
              setInterval(function() {
              // ...
              }.bind(this), 1000);
              },
              })


              B. use a closure



              methods:
              {
              tvTimer()
              const _this = this
              {
              setInterval(function() {
              _this.timer ...
              }, 1000);
              },
              })


              C. use an arrow function



              methods:
              {
              tvTimer()
              {
              setInterval(() => {
              this.timer ...
              }, 1000);
              },
              })


              This is one of those things one has to really understand about JS in order to not fall for it over and over in different places. I suggest this ebook:



              https://github.com/getify/You-Dont-Know-JS/blob/master/up%20%26%20going/ch2.md#this-identifier






              share|improve this answer
























              • Thanks, I did not know about binding and arrow functions. Will need to read up on it!

                – Liga
                Jan 2 at 10:51














              2












              2








              2







              Classic problem of this being not what you expect in a function



              A. bind it



              methods:
              {
              tvTimer()
              {
              setInterval(function() {
              // ...
              }.bind(this), 1000);
              },
              })


              B. use a closure



              methods:
              {
              tvTimer()
              const _this = this
              {
              setInterval(function() {
              _this.timer ...
              }, 1000);
              },
              })


              C. use an arrow function



              methods:
              {
              tvTimer()
              {
              setInterval(() => {
              this.timer ...
              }, 1000);
              },
              })


              This is one of those things one has to really understand about JS in order to not fall for it over and over in different places. I suggest this ebook:



              https://github.com/getify/You-Dont-Know-JS/blob/master/up%20%26%20going/ch2.md#this-identifier






              share|improve this answer













              Classic problem of this being not what you expect in a function



              A. bind it



              methods:
              {
              tvTimer()
              {
              setInterval(function() {
              // ...
              }.bind(this), 1000);
              },
              })


              B. use a closure



              methods:
              {
              tvTimer()
              const _this = this
              {
              setInterval(function() {
              _this.timer ...
              }, 1000);
              },
              })


              C. use an arrow function



              methods:
              {
              tvTimer()
              {
              setInterval(() => {
              this.timer ...
              }, 1000);
              },
              })


              This is one of those things one has to really understand about JS in order to not fall for it over and over in different places. I suggest this ebook:



              https://github.com/getify/You-Dont-Know-JS/blob/master/up%20%26%20going/ch2.md#this-identifier







              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered Jan 2 at 10:49









              Linus BorgLinus Borg

              11.9k13839




              11.9k13839













              • Thanks, I did not know about binding and arrow functions. Will need to read up on it!

                – Liga
                Jan 2 at 10:51



















              • Thanks, I did not know about binding and arrow functions. Will need to read up on it!

                – Liga
                Jan 2 at 10:51

















              Thanks, I did not know about binding and arrow functions. Will need to read up on it!

              – Liga
              Jan 2 at 10:51





              Thanks, I did not know about binding and arrow functions. Will need to read up on it!

              – Liga
              Jan 2 at 10:51













              1














              The function you pass to setInterval receives its own context, however if you use an arrow function it will use the current context instead, and ignore the one given by setInterval.



              setInterval(() => { ... }, 1000)





              share|improve this answer




























                1














                The function you pass to setInterval receives its own context, however if you use an arrow function it will use the current context instead, and ignore the one given by setInterval.



                setInterval(() => { ... }, 1000)





                share|improve this answer


























                  1












                  1








                  1







                  The function you pass to setInterval receives its own context, however if you use an arrow function it will use the current context instead, and ignore the one given by setInterval.



                  setInterval(() => { ... }, 1000)





                  share|improve this answer













                  The function you pass to setInterval receives its own context, however if you use an arrow function it will use the current context instead, and ignore the one given by setInterval.



                  setInterval(() => { ... }, 1000)






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Jan 2 at 10:45









                  UncleDaveUncleDave

                  2,835825




                  2,835825























                      0














                      This is because setInterval() this object is not same as vue.js this, since they have different scopes.



                      Try to assign this object to new variable before entering the problematic function's scope.



                      let self = this;
                      tvTimer()
                      {
                      setInterval(function() {
                      self.timer++;

                      if (self.timer == self.pages[self.current_page].interval) {
                      console.log('it is time!!');
                      }

                      console.log(self.pages[self.current_page].page);
                      }, 1000);
                      },


                      See: https://developer.mozilla.org/en-US/docs/Glossary/Scope






                      share|improve this answer




























                        0














                        This is because setInterval() this object is not same as vue.js this, since they have different scopes.



                        Try to assign this object to new variable before entering the problematic function's scope.



                        let self = this;
                        tvTimer()
                        {
                        setInterval(function() {
                        self.timer++;

                        if (self.timer == self.pages[self.current_page].interval) {
                        console.log('it is time!!');
                        }

                        console.log(self.pages[self.current_page].page);
                        }, 1000);
                        },


                        See: https://developer.mozilla.org/en-US/docs/Glossary/Scope






                        share|improve this answer


























                          0












                          0








                          0







                          This is because setInterval() this object is not same as vue.js this, since they have different scopes.



                          Try to assign this object to new variable before entering the problematic function's scope.



                          let self = this;
                          tvTimer()
                          {
                          setInterval(function() {
                          self.timer++;

                          if (self.timer == self.pages[self.current_page].interval) {
                          console.log('it is time!!');
                          }

                          console.log(self.pages[self.current_page].page);
                          }, 1000);
                          },


                          See: https://developer.mozilla.org/en-US/docs/Glossary/Scope






                          share|improve this answer













                          This is because setInterval() this object is not same as vue.js this, since they have different scopes.



                          Try to assign this object to new variable before entering the problematic function's scope.



                          let self = this;
                          tvTimer()
                          {
                          setInterval(function() {
                          self.timer++;

                          if (self.timer == self.pages[self.current_page].interval) {
                          console.log('it is time!!');
                          }

                          console.log(self.pages[self.current_page].page);
                          }, 1000);
                          },


                          See: https://developer.mozilla.org/en-US/docs/Glossary/Scope







                          share|improve this answer












                          share|improve this answer



                          share|improve this answer










                          answered Jan 2 at 10:55









                          niklazniklaz

                          1,97611217




                          1,97611217























                              -1














                              I think you have to bind it in this context. We do it this way in React classess.






                              share|improve this answer
























                              • how do you bind it?

                                – Liga
                                Jan 2 at 10:44











                              • You can use data.timer that is a better way

                                – Shakeel Ahmed
                                Jan 2 at 10:49
















                              -1














                              I think you have to bind it in this context. We do it this way in React classess.






                              share|improve this answer
























                              • how do you bind it?

                                – Liga
                                Jan 2 at 10:44











                              • You can use data.timer that is a better way

                                – Shakeel Ahmed
                                Jan 2 at 10:49














                              -1












                              -1








                              -1







                              I think you have to bind it in this context. We do it this way in React classess.






                              share|improve this answer













                              I think you have to bind it in this context. We do it this way in React classess.







                              share|improve this answer












                              share|improve this answer



                              share|improve this answer










                              answered Jan 2 at 10:44









                              Shakeel AhmedShakeel Ahmed

                              1519




                              1519













                              • how do you bind it?

                                – Liga
                                Jan 2 at 10:44











                              • You can use data.timer that is a better way

                                – Shakeel Ahmed
                                Jan 2 at 10:49



















                              • how do you bind it?

                                – Liga
                                Jan 2 at 10:44











                              • You can use data.timer that is a better way

                                – Shakeel Ahmed
                                Jan 2 at 10:49

















                              how do you bind it?

                              – Liga
                              Jan 2 at 10:44





                              how do you bind it?

                              – Liga
                              Jan 2 at 10:44













                              You can use data.timer that is a better way

                              – Shakeel Ahmed
                              Jan 2 at 10:49





                              You can use data.timer that is a better way

                              – Shakeel Ahmed
                              Jan 2 at 10:49


















                              draft saved

                              draft discarded




















































                              Thanks for contributing an answer to Stack Overflow!


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid



                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.


                              To learn more, see our tips on writing great answers.




                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function () {
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54004882%2fcannot-use-this-keyword-in-an-object-because-it-is-inside-another-function%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







                              Popular posts from this blog

                              MongoDB - Not Authorized To Execute Command

                              How to fix TextFormField cause rebuild widget in Flutter

                              in spring boot 2.1 many test slices are not allowed anymore due to multiple @BootstrapWith