Three.js - How to access created scene from another class

I want to pass my scene constant to another class and use it there. But when I try to use it, it gives error of

Uncaught (in promise) TypeError: Cannot read property ‘scene’ of undefined

The one in below is my main file which I do everything:

class Main
{
constructor()
{
    this.scene = new THREE.Scene();
    this.scene.background = new THREE.Color( 0xaaaaaa );
    .
    .
    .
     /* some other code */

}

Init()
{
    
    /* other code */

    // Define constructor class and PASS SCENE CONST to it
    const cityConstructor = new Constructor(1, this.scene); //<-- THIS IS WHERE I PASS
    cityConstructor.ConstructCity();
}
}


const main = new Main();
main.Init();

And this is the class I passed the variable:

export class Constructor{
constructor(cellWidth, scene){
    
    this.scene = scene;//document.getElementsByTagName("canvas")[0].scene; // I tried other things as well
    this.loader = new GLTFLoader();

}

LoadAsset(block, xPos, yPos)
{
    // load a resource
    this.loader.load( 
        '../assets/'+ block.name,

        function ( gltf ) {
            const model = gltf.scene;
            model.position.set(xPos, 0, yPos);
            this.scene.add( model ); // <--- THIS IS WHERE ERROR IS

        },
         /*Other code*/

    );
}
 .
 .
 .
 /* Other code */

Now I want to ask what is best practice for accessing THREE.scene object from other classes?

/cc

This is my question.

The this reference is not pointing to the instance of Constructor. Try using an arrow function or save the this reference like so:

const scope = this;

// load a resource
this.loader.load( 
    '../assets/'+ block.name,

    function ( gltf ) {
        const model = gltf.scene;
        model.position.set(xPos, 0, yPos);
        scope.scene.add( model ); // <--- THIS IS WHERE ERROR IS

    },
     /*Other code*/

);
2 Likes

it’s just one of those awkward javascript things, they should have made sure that all class functions bind this but they didn’t so now you have to do this:

class Foo {
  constructor(scene) {
    this.scene = scene
  }

  LoadAsset = (block, x, y) => {
    this.scene.add(...) // 👍
  }
}

I couldn’t understand what you mean. I already using “this” keyword before accessing “scene” variable so what should I do differently?

Should I define scope constant in constructor?

i think i got confused as well, this must work:

LoadAsset(block, x, y) {
  this.loader.load(url, gltf => {
    this.scene.add(gltf.scene)

there is a difference in javascript between function (gltf) { and gltf =>, you should always use the latter for callbacks. the former will not bind this. i made it a habit to use => for class methods as well so that i can use them as callbacks.