[SOLVED!]Error while destroying one button by clicking on it

After hours of researching I really couldn’t make it right, it’s a very simple functionality.
but i always got error message, as I destory this button

playcanvas-stable.dbg.js:33991 Uncaught TypeError: Cannot read property ‘active’ of null

here is the code, very simple but i dont know what is wrong,

var BtnStates = pc.createScript(‘btnStates’);

// initialize code called once per entity
BtnStates.prototype.initialize = function() {

this.entity.element.on('click', this.onRelease, this);

};

BtnStates.prototype.onRelease = function () {

this.entity.destroy();

};

Seems to work fine for me?

https://playcanvas.com/editor/scene/641477

Can you share your project?

https://playcanvas.com/editor/scene/540521

please check uiManager.js / productManager.js

as most of the code are in them. (BTW, PRESS KEY_S to clone and generate those button list)

I tested as well, if it was running on a single button, there won’t be any issue while destroying it,
but actually in my project, the button is a clone, and when I click the button to destroy himself it will goes wrong (anyway it was destroyed as well, just got error message)

Turns out my project was a fluke.

A button has both an element and a button component and at the moment, you are putting a callback for ‘click’ on the element. The issue is that the button component is also listening for this event so what is happening is:

  • User clicks on the button UI
  • Element fires ‘click’ event
  • btnStates callback is called
  • Entities are destroyed
  • button component callback is called
  • engine crashes because the button data was destroyed

The fix is to put your callback in btnStates on the button and not the element

var BtnStates = pc.createScript('btnStates');

// initialize code called once per entity
BtnStates.prototype.initialize = function() {
    this.entity.button.on('click', this.onRelease, this); 
};

// When the cursor enters the element assign the hovered texture
BtnStates.prototype.onRelease = function () {
    this.entity.button.off('click', this.onRelease, this);
    this.entity.parent.enabled = false;
};
1 Like

Grazie ! yaustar

since the problem is that we need to turn the button listener off before destroying it.

That wasn’t the problem. That was just extra on my part of cleaning up.