I am trying to implement a method, where a angular material tab change happens after a fixed time interval. I tried using setInterval in JavaScript, but it doesnt work very reliable (the tab change occurs randomly). The code posted below works, but after some hours the browser freezes and the console shows this error:
ERROR RangeError: Maximum call stack size exceeded
togglePlay(): void {
this.isAnimationPlaying = !this.isAnimationPlaying;
if (this.isAnimationPlaying) {
this.setIndex();
} else {
clearTimeout();
}
}
setIndex() {
this.selectedIndex = (this.selectedIndex + 1) % this.matTabLength;
this.changeDetectorRef.detectChanges();
if (this.isAnimationPlaying) {
setTimeout(this.setIndex.bind(this), this.transitionSpeed);
} else {
clearTimeout();
}
}
I tried passing the transitionSpeed in the setTimeout method like this:
setTimeout(this.setIndex, this.transitionSpeed, this.transitionSpeed);
setIndex(transitionSpeed: number, selectedIndex: number, matTabLength: number) {
this.selectedIndex = (selectedIndex + 1) %.matTabLength;
if (this.isAnimationPlaying) {
setTimeout(this.setIndex, transitionSpeed, selectedIndex, matTabLength);
} else {
clearTimeout();
}
}
But if the method is called a second time, this.transitionSpeed is null.
Any help is highly appreciated
EDIT:
Changed code to this but still getting the same error after some hours:
togglePlay(): void {
this.isAnimationPlaying = !this.isAnimationPlaying;
if (this.isAnimationPlaying) {
this.setIndex();
} else {
clearTimeout(this.timerId);
}
}
setIndex() {
this.selectedIndex = (this.selectedIndex + 1) % this.matTabLength;
this.changeDetectorRef.detectChanges();
if (this.isAnimationPlaying) {
clearTimeout(this.timerId);
this.timerId = setTimeout(this.setIndex.bind(this), this.transitionSpeed);
} else {
clearTimeout(this.timerId);
}
}
EDIT2: While changing the Tab a TabChange event is called. Code:
tabChanged(event) {
this.themeClassesToRemove = Array.from(this.overlayContainer.getContainerElement().classList).filter((item: string) => item.includes('-template'));
if (Array.from(this.overlayContainer.getContainerElement().classList).filter((item: string) => item.includes('-template')).length) {
this.overlayContainer.getContainerElement().classList.remove(...this.themeClassesToRemove);
}
const label = event.tab.textLabel;
if (label.toLocaleLowerCase() === '1') {
this.templateService.default_template = this.templateService.grey_template;
} else if (label.toLocaleLowerCase() === '2') {
this.templateService.default_template = this.templateService.green_template;
} else if (label.toLocaleLowerCase() === '3') {
this.templateService.default_template = this.templateService.red_template;
} else {
this.templateService.default_template = this.templateService.blue_template;
}
this.overlayContainer.getContainerElement().classList.add(this.templateService.default_template);
window.dispatchEvent(new Event('resize'));
}
This is the only method, which is called beside the timeout. According to this post, there must be recirsive method which is called all the time.