0

I don't know the reason, why comes the error ***.setAttribute is not a function. Can some one explain it? Porject:https://glitch.com/edit/#!/skill-lab?path=public/js/cursorsubmit.js:10:8 Thanks in advance.

AFRAME.registerComponent('cursor-submit', {
  init: function () {
    var _this=this;
    this.el.addEventListener('click', function (evt) {
      this.setAttribute('material', 'color', 'red');
      //_this.setAttribute('material', 'color', 'green'); //_this.setAttribute is not a function
      //this.setAttribute('material', 'color', 'green'); //works well
      setTimeout(function(){
        //alert(_this); //works well
        this.setAttribute('material', 'color', 'green');  //this.setAttribute is not a function
        //_this.setAttribute('material', 'color', 'green'); //_this.setAttribute is not a function
      },2000);
    });
  }
});
L3 Zhang
  • 95
  • 1
  • 13
  • 1
    Related: [How to access the correct `this` context inside a callback?](https://stackoverflow.com/questions/20279484/how-to-access-the-correct-this-context-inside-a-callback) – Jonathan Lonowski Jul 10 '17 at 15:10
  • FYI the `this` problem is explained in detail here in the docs: https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout – Jamiec Jul 10 '17 at 15:11
  • @Jamiec its not a question about the context, read the code, he didnt know how to access the cursor element (via this.el, not this, so the line should be let _this = this.el), please post the question again, but uncomment the proper context lines. – Piotr Adam Milewski Jul 10 '17 at 15:15
  • @PiotrAdamMilewski The code depends on a particular `this` value when inside the timeout function, which isn't being managed in the code – by binding or variables. Both of those options are precisely what the related Q&A explains. – Jonathan Lonowski Jul 10 '17 at 15:17
  • @PiotrAdamMilewski Im so sorry that all of our mind-reading skills are not as advanced as yours. One could argue that this is why we ask for well described questions with a [mcve] to back them up. It saves people getting butthurt when we misidentify their questions! – Jamiec Jul 10 '17 at 15:17
  • if You use _this.el, it will be working fine. Either create a let _this = this.el; reference, or use it like this: let _this = this; -> _this.el. – Piotr Adam Milewski Jul 10 '17 at 15:18
  • @PiotrAdamMilewski you're also totally wrong! Inside the event handler `this` does refer to the clicked element. Inside the `setTimeout` the contect of `this` is lost. Its inside the event handler that one needs to cache the reference to `this` for use later – Jamiec Jul 10 '17 at 15:19
  • @JonathanLonowski For some reason he commented the proper context lines, which would still not work, for he is trying to set the attributes to the wrong object – Piotr Adam Milewski Jul 10 '17 at 15:20
  • @Jamiec I;ve got a working remix here https://glitch.com/edit/#!/right-bowl?path=public/js/cursorsubmit.js:4:23 – Piotr Adam Milewski Jul 10 '17 at 15:21
  • @PiotrAdamMilewski getting something "working" is not a complete measure of success. Inside the `init` you've cached an object called `_this` which **does not refer to this** in a sensible way. You would be better to cache `_this` *inside the event handler* where it actually makes sense. – Jamiec Jul 10 '17 at 15:22
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/148797/discussion-between-piotr-adam-milewski-and-jamiec). – Piotr Adam Milewski Jul 10 '17 at 15:23
  • Let us not. Look here - this will work just as well, and not misname variables as `this` which are not actually `this`: https://jsfiddle.net/5rLpn06k/ (I wont be responding again) – Jamiec Jul 10 '17 at 15:25
  • @jamiec i just wrote, that i got way ahead in overinterpreting what OP was trying to do earlier, btw good example in the fiddle. – Piotr Adam Milewski Jul 10 '17 at 15:29
  • @Jamiec and PiotrAdamMilewski, thanks for you discussion. I have learnt much from you two. – L3 Zhang Jul 11 '17 at 09:45
  • Jamiec and @PiotrAdamMilewski, thanks for you discussion. I have learnt much from you two. – L3 Zhang Jul 11 '17 at 09:46
  • Before i didn't understand the difference between this and this.el. Now i learned it from you two. Thank you very much. – L3 Zhang Jul 11 '17 at 09:56

1 Answers1

0

I see you created a variable _this. Why don't you use that inside of your setTimout?

Mickers
  • 1,367
  • 1
  • 20
  • 28
  • There appear to be 2 objects involved – frame and element. But, I think you're close. `_this.el.setAttribute(...)` may work well. – Jonathan Lonowski Jul 10 '17 at 15:14
  • @Jonathan Lonowski it works with you methode. Before i didn't understand the usage of .el. Now i learned it from you and the discussion. Thanks a lot. – L3 Zhang Jul 11 '17 at 09:53
  • @Micker _this = this should be _this = this.el, or it dosen't work – L3 Zhang Jul 11 '17 at 10:00