Structural code-issue regarding 'setTimeout'

[To those in charge of backend API/code structure within the pc.-architechture]

Once again I seem to find some troubling issues in regards to the workings of ‘setTimeout’.
Within a piece of code, I need to pause a certain execution in relation to calling a function that might run an .enabled command on a model too early.

But anyways here it is:

As I call this line within a function:

self.allCarsGone(); setTimeout(self.setraOn, 300);

I experience that this executes ok:

HtmlHandler.prototype.allCarsGone =  function(){
    this.lamboGone = this.app.root.findByName('Lambo'); this.setraGone = this.app.root.findByName('Setra'); this.ducatoGone = this.app.root.findByName('Ducato');
    this.lamboGone.enabled = false; this.setraGone.enabled = false; this.ducatoGone.enabled = false;
    // Reset all cameras:
    this.activeCameraSplitDucatoUd = this.app.root.findByName('CameraSplitDucato');      this.activeCameraSplitDucatoUd.enabled = false;
    this.activeCameraSplitLamboUd  = this.app.root.findByName('CameraSplitLambo');       this.activeCameraSplitLamboUd.enabled = false;
    this.activeCameraSplitSetraUd  = this.app.root.findByName('CameraSplitSetra');       this.activeCameraSplitSetraUd.enabled = false;    
    this.activeCameraSplitIndFraJ  = this.app.root.findByName('CameraSplitJumpy');       this.activeCameraSplitIndFraJ.enabled =  false;
};
  • while this:
HtmlHandler.prototype.setraOn = function(){
    var app = this.app;
    
    console.log("MSelf"+ app.root.findByName('Lambo')); 
    this.lamboGone = this.app.root.findByName('Lambo');
        this.setraTopEntLvl = this.app.root.findByName('SetraEnt');  this.setraTopEntLvl.enabled = true;  
        this.setra = this.app.root.findByName('Setra');  this.setra.enabled = true;  
        // Venstre side-udsyn ; HalveX/HeleY:
        this.activeCamera1.camera.rect = new pc.Vec4(0, 0, 0.498, 1); 
        // Hoejre side-udsyn ; HalveX/(To Kvarte) HalveY:
        this.activeCameraSplitSetraUd = this.app.root.findByName('CameraSplitSetra'); this.activeCameraSplitSetraUd.enabled = true;       this.activeCameraSplitSetraUd.camera.rect = new pc.Vec4(0.5, 0.5, 0.495, 0.495); 
        this.activeCameraSplitIndFraJ = this.app.root.findByName('CameraSplitJumpy'); this.activeCameraSplitIndFraJ.enabled =  true;      this.activeCameraSplitIndFraJ.camera.rect = new pc.Vec4(0.5, 0, 0.495, 0.495); 
};
  • gives me an error of:

Uncaught TypeError: Cannot read property ‘root’ of undefined

TypeError: Cannot read property ‘root’ of undefined
at HtmlHandler.setraOn (https://launch.playcanvas.com/api/assets/files/Script/HTMLtxtField/htmlHandler.js?id=22760179&branchId=ecf80571-4d50-4ebc-894b-849ad9a16761:192:30)

Motivation: this is not the 1st time that ‘setTimeout’ messes things up for me.
Futhermore: please read Using setTimeout to fade in objects

PS: I just got this workaround to function as wished-for [which should not be confused with a ‘SOLVED’-conclusion >> this being a ‘Feedback’; I guess we all want better architecture instead?]:

  self.allCarsGone();
  for(var timeP=0; timeP<1000000; timeP++){
            var pauseAlittle;
           }
  self.setraOn();

Your setTimeout callback will be in a different scope. Try doing:

var self = this;
setTimeout(function() {
    self.setraOn();
}.bind(this), 300);

Using loops to create a timeout is not a good way of doing things…

1 Like

Actually, I think you would do either:

setTimeout(function() {
    this.setraOn();
}.bind(this), 300);

Or:

var self = this;
setTimeout(function() {
    self.setraOn();
}, 300);

But yes, this all originates from a misunderstanding of this. Maybe try reading this:

1 Like

Also in hindsight, if you want to delay something I always like doing a quick, empty tween instead because it runs in the update loop of the app versus in the window. So if the tab is inactive, the timer stops counting down and resumes as normal when the app is active again.

this.app.tween({}).to({}, 1, pc.Linear)
    .on('complete', function() {
        // do whatever here
    }, this).start();
3 Likes

Because …?

Presumably because it’ll execute at different speeds on different devices. :slight_smile:

1 Like

I was trying to use the clear timeout function but it’s not working

var Timeout_1=setTimeout(function () { //some action },5000); // calling in function A
clearTimeout(Timeout_1);//calling in function B

Hello @Sravs_techm and Welcome!

var Timeout_1 = setTimeout(function() {
    // some code
}.bind(this), 5000);

clearTimeout(Timeout_1);

Can you please try like this check if it working or not?

Hi @Ketan_ATA it’s working Thank you

1 Like