Search code examples
javascriptaframewebvr

On an A-Frame component, how do you share data between functions?


I'm making an A-Frame component and I want to share data between functions like init and other custom component handlers.

I figured out how to add to the component schema to allow for input from the DOM to set a variable using this.data following this doc: https://aframe.io/docs/0.4.0/core/component.html#component-prototype-properties

However I am having trouble, sometimes the value of this.data reverts back to the initial state from the DOM, not reflecting runtime modifications. Is there a better way to share data across a component?


Solution

  • There are two recommended ways of storing data in an A-Frame component, similar to public and private properties.

    Schema (public)

    Properties declared in the component's schema are public, and can be set with setAttribute and accessed with both getAttribute and this.data.____. NOTE: It is not safe to modify this.data directly, because A-Frame will overwrite the data when receiving updates from the DOM.

    HTML:

    <a-entity foo="bar: 10"></a-entity>
    

    JS:

    AFRAME.registerComponent('foo', {
      schema: {
        bar: {default: 25}
      },
      init: function () {
        console.log(this.data.bar); // 10
    
        this.data.bar = 5; // THIS CHANGE MAY BE LOST.
      },
      doStuff: function () {
        console.log(this.data.bar); // 10
        this.el.setAttribute('bar', 'foo', 15);
        console.log(this.data.bar); // 15
      }
    });
    

    Properties (private)

    For data meant to be used within a component, you can also assign them directly to this. This is the best option when data will only be used within the component, and doesn't need to be declared in the HTML.

    JS:

    AFRAME.registerComponent('foo', {
      init: function () {
        this.baz = 'hello';
        console.log(this.baz); // hello
      },
      doStuff: function () {
        console.log(this.baz); // hello
        this.baz = 'bonjour';
        console.log(this.baz); // bonjour
      }
    });