I am attempting to call a method within itself in Vue, however I'm getting the following error
this.loop is not a function. (In 'this.loop()', 'this.stagger' is undefined)
here is the method:
loop: function () {
var n = $(".item").length;
var i = 1;
var m = n + 5;
setTimeout( function () {
$('.item:nth-child('+i+')').addClass('show');
var x = i - 2;
var y = x - 2;
i = i + 3;
// for 2 columns:
// x = i - 1;
// i = i + 2;
$('.item:nth-child('+x+')').addClass('show');
$('.item:nth-child('+y+')').addClass('show'); // remove for 2 columns
if (i < m) {
this.loop() // error occurs here
}
}, 100)
}
I am attempting to call a method within itself in Vue, however I'm getting the following error
this.loop is not a function. (In 'this.loop()', 'this.stagger' is undefined)
here is the method:
loop: function () {
var n = $(".item").length;
var i = 1;
var m = n + 5;
setTimeout( function () {
$('.item:nth-child('+i+')').addClass('show');
var x = i - 2;
var y = x - 2;
i = i + 3;
// for 2 columns:
// x = i - 1;
// i = i + 2;
$('.item:nth-child('+x+')').addClass('show');
$('.item:nth-child('+y+')').addClass('show'); // remove for 2 columns
if (i < m) {
this.loop() // error occurs here
}
}, 100)
}
Share
Improve this question
asked Feb 25, 2018 at 8:04
Robert TillmanRobert Tillman
1,0132 gold badges13 silver badges22 bronze badges
1 Answer
Reset to default 14This is because this
no longer refers to the object when in the callback function of setTimeout
. There are several solutions.
You could change the function
to an arrow function:
setTimeout( () => {
That way this
will retain its original value, also within the callback.
Or, you could bind this
to the function:
setTimeout( function () {
// ...
}.bind(this), 100)
//^^^^
Or, you could copy this
and use that instead:
var that = this;
setTimeout( function () {
// ...
that.loop();
// ...
}, 100)
Avoiding reinitialisation
Currently your recursive calls will also reset the variables, including i
.
Solve this, by passing i
as argument:
loop: function (i = 1) { // <<---- default value
var n = $(".item").length;
var m = n + 5;
if (i >= m) return; // <<-----
setTimeout(() => {
$('.item:nth-child('+i+')').addClass('show');
var x = i - 2;
var y = x - 2;
$('.item:nth-child('+x+')').addClass('show');
$('.item:nth-child('+y+')').addClass('show');
this.loop(i+3); // <<------
}, 100);
}