calling declared js function

Game development with Board Game Arena Studio
Post Reply
User avatar
Ginso
Posts: 26
Joined: 16 July 2020, 19:45

calling declared js function

Post by Ginso »

hello,
in my js file i have declared some utility functions like

Code: Select all

updateLP:function() {
    //...
 },
usually i can call it with this.updateLP() what if i want to call it inside the onEnd function of a dojo animation like

Code: Select all

dojo.animateProperty({node:"tmpcard", 
		properties: {
			left:dest.x-rect.x,
			top:dest.y-rect.y},
		onEnd: function() {
		        this.updateLP(); //<-- doesn't work
		}
	}).play();
obviously it doesn't work because "this" refers to something else now. How can i still use it?
User avatar
Tisaac
Posts: 2743
Joined: 26 August 2014, 21:28

Re: calling declared js function

Post by Tisaac »

You can use arrow functions that keep the scope of where the function is defined :

Code: Select all

dojo.animateProperty({node:"tmpcard", 
		properties: {
			left:dest.x-rect.x,
			top:dest.y-rect.y},
		onEnd: () => this.updateLP(); // work
	}).play();
User avatar
joezg
Posts: 70
Joined: 16 June 2011, 17:17

Re: calling declared js function

Post by joezg »

Ginso wrote: 25 July 2020, 11:06 hello,
in my js file i have declared some utility functions like

Code: Select all

updateLP:function() {
    //...
 },
usually i can call it with this.updateLP() what if i want to call it inside the onEnd function of a dojo animation like

Code: Select all

dojo.animateProperty({node:"tmpcard", 
		properties: {
			left:dest.x-rect.x,
			top:dest.y-rect.y},
		onEnd: function() {
		        this.updateLP(); //<-- doesn't work
		}
	}).play();
obviously it doesn't work because "this" refers to something else now. How can i still use it?
Problem here is that onEnd function is bound to the object on which it is called. In this case, you can assume that it is the object you sent to dojo.animateProperty. That object doesn't have updateLP property and program crashes. You can bind this function explicitly to your game table object with bind function like this:

Code: Select all

dojo.animateProperty({node:"tmpcard", 
		properties: {
			left:dest.x-rect.x,
			top:dest.y-rect.y},
		onEnd: function() {
		        this.updateLP(); //<-- doesn't work
		}.bind(this)
	}).play();
You can see more about this here:
https://developer.mozilla.org/en-US/doc ... ators/this

As mentioned before, you can use arrow functions, which retain this value of enclosing context. A slight problem with arrow functions is that they are 95% supported right now. This should be enough of a support to use it in your code, but could expect some bug report due to this.
User avatar
Tisaac
Posts: 2743
Joined: 26 August 2014, 21:28

Re: calling declared js function

Post by Tisaac »

Bind was definitively the way to go before arrow function, notice that you could do a bit shorter here (since functions are objects) :

Code: Select all

onEnd: this.updateLP.bind(this)
Just so you know, you could also do the "old school way" (that's actually what babeljs do when you transpile to ECMA3) :

Code: Select all

var _this = this;
dojo.animateProperty({node:"tmpcard", 
		properties: {
			left:dest.x-rect.x,
			top:dest.y-rect.y},
		onEnd: function() {
		        _this.updateLP(); //<-- work
		}
	}).play();
Post Reply

Return to “Developers”