Dynamically creating buttons but won't retrieve data from it

Hi!

I am iterating through a for loop to create 10 buttons dynamically. It works all fine however I am not being able to retrieve “myid” value.

This is my sample code (which belongs to a class type scene):

preload() {
    this.load.image("btnLevel","assets/buttons/btnLevel.jpg");
}

create() {
    for (var a=1; a<=10; a++) {
        var mybutton = this.add.image(60*a, 30, "btnLevel").setInteractive();
        mybutton.myid = "btnLevel" + a;
        mybutton.on("pointerup", function (e) {
           console.log(this.myid);
        }, this);
    }
}

Any clue?

Because when you make the pointerup event on the button, you’re setting the scene as ‘this’. So what happens when you press the button, then it logs “Scene.myid”

mybutton.on("pointerup", function (e) {
   console.log(this.myid);
});

just by removing the ‘this’ from the event, then it works.

Edit: You could also replace ‘this’ with ‘mybutton’, but that’d be the same as removing it.

Thenonamezz, as advised I tried this:

mybutton.on("pointerup", function (e) {
   console.log(myid);
});

Now it produced the following error:

Uncaught ReferenceError: myid is not defined

Any idea?

e.myid

you still need the ‘this’ inside of the event.

‘this’ inside of the event, is the scope - in this case the button.
the other ‘this’ (3rd parameter), is to set the scope, so if you passed ‘this’, then you set the scope to be the scene.

tl;dr
do this.myid and dont put ‘this’ as a 3rd parameter

tl;dr;dr

mybutton.on("pointerup", function (e) {
   console.log(this.myid);
});

Thenonamezz, it kind of fixed the issue but created me another one. I need the third this as parameter because it’s the only way of navigating between scenes. In fact I failed on not put the complete code before. My bad. Look that:

create() {
    for (var a=1; a<=10; a++) {
        var mybutton = this.add.image(60*a, 30, "btnLevel").setInteractive();
        mybutton.myid = "btnLevel" + a;
        mybutton.on("pointerup", function (e) {
           this.scene.switch("sceneNext", { 
               "level": this.myid}); 
        }, this);
    }
}

When I remove the third this parameter it will give me the following new error:

Uncaught TypeError: this.scene.switch is not a function

Geez!

Milton, e.myid produces the very same Uncaught ReferenceError: myid is not defined error.

I don’t know if it will help some yet but I figured that if I do:

console.log(this.children.list[index].myid);

Where “index” is the value of the button in the array, it will return me the desired contents. However to do that I would need to get “index” from somewhere and I couldn’t find any identifier in this wich provides it.

You could make a variable outside of the for-loop that is a reference to the scene:

let myScene;
    create() {
        myScene = this;
        for (var a=1; a<=10; a++) {
            var mybutton = this.add.image(60*a, 30, "btnLevel").setInteractive();
            mybutton.myid = "btnLevel" + a;
            mybutton.on("pointerup", function (e) {
               myScene.scene.switch("sceneNext", { 
                   "level": this.myid}); 
            });
        }
    }
1 Like

Thenonamezz it definitively did the trick!

A few seconds before to see your post and after to understand that the third this parameter referred to the scope of the project (I really didn’t know that, thank you very much for putting a light over that) I had the idea of replace the this with the game var (from game = new Phaser.Game(config)). So instead of:

this.scene.switch("sceneNext", { 
   "level": this.myid});

I did:

game.scene.switch("sceneNext", { 
   "level": this.myid});

And it produced the very same result that is exactly what you suggested!

Thanks for all your patience and efforts!

:blush:

    this.input.on('gameobjectdown', onObjectClicked);

function onObjectClicked(pointer, gameObject) {
    console.log(gameObject.myid)
}
1 Like

Thanks Milton!