Search code examples
schemaentityaframe

How does an aframe entity defaults to the schema ones if no data is passed on


I'm having some difficulties in understanding how in aFrame an entity works with schema and data together. Forgive me, I'm a bit new in the library and maybe I'm missing something. Thanks.

Consider the following:

// register the aframe component (Button.js):

import { registerComponent, THREE } from 'aframe'

const button = registerComponent('button', {
  schema: {
    width: { type: 'number', default: 0.6 },
    height: { type: 'number', default: 0.40 },
    color: { type: 'string', default: 'orange' },
  },
  init: function() {
    const schema = this.schema // Schema property values.
    const data = this.data // Component property values.
    const el = this.el // Reference to the component's entity.

    // Create geometry.
    this.geometry = new THREE.BoxBufferGeometry(data.width || schema.width.default, data.height || schema.height.default, data.depth || schema.depth.default)

    // Create material.
    this.material = new THREE.MeshStandardMaterial({ color: data.color || schema.color.default })

    // Create mesh.
    this.mesh  = new THREE.Mesh(this.geometry, this.material)

    // Set mesh on entity.
    el.setObject3D('mesh', this.mesh)
  }
})

export default button

// add the entity in the app (App.js)
import button from './Button'

<a-entity button="width: 0.4; height: 0.4: color: 'green'" position="0 0 0"></a-entity>

Now with the example above I would expect that my component will use data instead of schema defaults. And if I would instead just do:

<a-entity button position="0 0 0"></a-entity>

It would use the schema default ones. Is this how it should be done? I've been seeing a lot of examples where people just use data. Thanks


Solution

  • The schema isn't intended to be used directly. From the docs:

    The schema defines the properties of its component. (...) The component’s property type values are available through this.data

    The idea goes like this:

    • You define the properties (with defaults) in the schema

      schema {
        prop: {default: "default value"}
      },
      
    • You access the values with this.data[prop_name]:

      init: function() {
        console.log("prop value at init:", this.data.prop)
      },
      
    • You can monitor the property updates (like via setAttribute("propname", "newValue") within the update handler:

      update: function(oldData) {
           console.log("prop changed from", oldData.prop, "to", this.data.prop)
      },
      

    In a setup like this:

    <!-- this.data.prop will contain the default values -->
    <a-entity foo></a-entity>
    
    <!-- this.data.prop will contain the new value -->
    <a-entity foo="prop: value></a-entity>