0

I am trying to access data obtained from an event listener function in init() in another function in an aframe component. I have tried to use binding so that the data obtained in the event listener can be bound to "this" space.

Here is my code

AFRAME.registerComponent('move', {
  schema: {    
  },
  
  init: function() {    
    
    this.el.sceneEl.addEventListener('gameStarted', testfun.bind(this), {once: 
    true});
    
    function testfun(e){      
        this.speed = e.detail.source;
        console.log(this.speed); // I get proper values here
    }
    console.log(this.speed);  // value is not updated and I only get "undefined"
  },

  tick: function(t, dt) {
    console.log(this.speed); // I get undefined
  }

});

I thought if I bind this to function, I can access the data outside the even listener scope as well. Could you please spare a little time to help me figure this out?

2 Answers 2

1

The reason is that the variable (speed) you are modifying is out of scope. Since you have declared a new function testfun with its own properties in function init. If you can use ES5+ syntax then you can declare testfun as an arrow function instead and you are done. For more read about here: https://zendev.com/2018/10/01/javascript-arrow-functions-how-why-when.html

try this:

AFRAME.registerComponent("move", {
  schema: {},

  init: function() {
    this.speed = 0;
    this.el.sceneEl.addEventListener("gameStarted", testfun, {
      once: true
    });
    const testfun = e => {
      this.speed = e.detail.source;
      console.log(this.speed); // I get proper values here
    };
    console.log(this.speed); // value is not updated and I only get "undefined"
  },

  tick: function(t, dt) {
    console.log(this.speed); // I get undefined
  }
});
Sign up to request clarification or add additional context in comments.

3 Comments

I attach the "move" component to the entity conditionally after the gamestarted event gets fired. I am using aframe-state component to achieve that. So, I am able to get the value of speed inside the even listener but not outside the scope which is what I am trying to achieve.
I am not sure what's wrong but it is still not working. I tried the exact code that you have given. I am not getting the value of speed outside the testfun as 0 ( the initialized value)
Read my answer below: by the time you access the variable the gameStarted event has not yet fired
1

That’s expected behavior. You have probably not realized that events will fire at any arbitrary time, after your console.log calls. By the time init runs this.speed is not yet initialized. You have to wait until gameStarted event fires to get a value. The same goes for tick before the event fires. Give this.speed an initial value to avoid undefined

AFRAME.registerComponent('move', {
  schema: {    
  },

  init: function() { 
    var self = this;   
    this.speed = 0;
    this.el.sceneEl.addEventListener('gameStarted', testfun.bind(this), {once: 
    true});

    function testfun(e){      
        self.speed = e.detail.source;
        console.log(self.speed); // I get proper values here
    }
    console.log(this.speed);  // value is not updated and I only get "undefined"
  },

  tick: function(t, dt) {
    console.log(this.speed); // I get undefined
  }

2 Comments

Thank you Diego. Actually this component "move" is attached to the entity conditionally with the condition being the event gameStarted being fired. Therefore, the init function will get executed after that event has been fired. I achieve this conditional attachment/detachment using aframe-state component. I have now realised that attaching and detaching this component based on the event does not let me persist with the value of this.speed. I have now changed my code to remove this condition so now this issue is resolved. Thank you so much for your help.
If the event fires before init, it wont be captured either by testfun. You need to attach the eventlistener and then wait for the event to be fired. You should be able to store the variable in the component. I recommend familiarization with how javascript scoping works: css-tricks.com/javascript-scope-closures

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.