[SOLVED] Tweening and scope for this.app.fire on complete

Hi

I am getting an error when using tween in a script where the.app.fire is undefined (see below), I can access it in the initialize method, is this a scoping issue? The tween is working as expected and hitting the complete method. Thanks for any help.

Cheers
Badu

Tween code:

this.entity
        .tween(this.entity.getLocalPosition())
        .to(new pc.Vec3(this.entity.getLocalPosition().x, this.entity.getLocalPosition().y, -0.007), 2.0, pc.SineOut)
        .on('complete', function () {
            this.inPosition = true;
            this.moving = false;
            this.app.fire("input:ready");
        })
        .start();

Error (Stack trace):
[ball.js?id=8286523:36]: Uncaught TypeError: Cannot read property ‘fire’ of undefined

TypeError: Cannot read property ‘fire’ of undefined
at Tween. (launch.playcanvas.com/api/assets/files/scripts/ball.js?id=8286523:36:21)
at Tween.fire (code.playcanvas.com/playcanvas-stable.dbg.js:608:18)
at Tween.update (launch.playcanvas.com/api/assets/files/scripts/tween.js?id=8286295:405:26)
at TweenManager.update (launch.playcanvas.com/api/assets/files/scripts/tween.js?id=8286295:24:37)
at Application. (launch.playcanvas.com/api/assets/files/scripts/tween.js?id=8286295:672:39)
at Application.fire (code.playcanvas.com/playcanvas-stable.dbg.js:608:18)
at Application.update (code.playcanvas.com/playcanvas-stable.dbg.js:19544:10)
at code.playcanvas.com/playcanvas-stable.dbg.js:19879:11

Maybe this is related to javascript’s dynamically binding this. You can simply assign self to this, and use self instead of this in the function.

var self = this;
this.entity
    .tween(this.entity.getLocalPosition())
    .to(new pc.Vec3(this.entity.getLocalPosition().x, this.entity.getLocalPosition().y, -0.007), 2.0, pc.SineOut)
    .on('complete', function () {
        self.inPosition = true;
        self.moving = false;
        self.app.fire("input:ready");
    })
    .start();

or use arrow function instead of normal function:

//...
    .on('complete', () => {
        this.inPosition = true;
        this.moving = false;
        this.app.fire("input:ready");
    });
1 Like

I’d use the former since arrow functions aren’t supported in IE11.

Thanks Will, that did the trick

Adding to this, be sure to pass the callback scope through your listeners.

this.app.on(“input:showAnswer”, this.onShowAnswer, this);

1 Like

I’m using pc.app.fire in those kinds of functions.
They clearly resolve the same way - is one more efficient / correct ?

I guess technically there could be more than one app on a page, so this.app ensures that it’s the one that created the entity.