This is probably beyond the intended scope of Alpine, but if anyone can shed light on this problem I'd be grateful. I have a component:
<div x-data="foobar()" x-init="initialise()"></div>
function foobar() {
return {
run() {
window.requestAnimationFrame(this.run);
// do some animated stuff here
},
initialise() {
this.run();
}
}
}
This produces the error:
TypeError: this is undefined
in reference to the line with requestAnimationFrame. Any idea whether this is possible with Alpine?
Yeah, it's normal javascript at that point. The context of the callback is not the object so you can't use this but you can do const self = this at the beginning of the run function and then you should be able to use self.run() in your requestAnimationFrame callback.
Thanks @SimoTod - I should have said I've tried that, i.e.:
run() {
let that = this;
window.requestAnimationFrame(that.run);
}
produces the error
TypeError: that is undefined
and if I try:
window.requestAnimationFrame(that.run());
I get a "too much recursion" error...
It would be something like
run() {
const that = this
window.requestAnimationFrame(() => that.run())
},
if you pass that.run(), you are not passing a callable but the result of that function, to calculate the result, the engine needs to execute run(), which calls requestAnimationFrame, which needs the result of that.run and so on.
If you need to support ie11, you can also use
run() {
const that = this
window.requestAnimationFrame(function() {that.run()})
},
or
run() {
window.requestAnimationFrame(function() {this.run()}.bind(this))
},
Gah of course. Thanks for the advice, it's working now.
It would be something like
run() { const that = this window.requestAnimationFrame(() => that.run()) },if you pass that.run(), you are not passing a callable but the result of that function, to calculate the result, the engine needs to execute run(), which calls requestAnimationFrame, which needs the result of that.run and so on.
If you need to support ie11, you can also use
run() { const that = this window.requestAnimationFrame(function() {that.run()}) },or
run() { window.requestAnimationFrame(function() {this.run()}.bind(this)) },
run() {
// Do stuff
requestAnimationFrame(() => this.run())
})
Is enough
Most helpful comment
Is enough