0

I want to build slider in angular2, but i have a lot of trouble with it. Ok, let's go to main problem. Why is this function getting me this error

"ERROR Error: Uncaught (in promise): RangeError: Maximum call stack size exceeded RangeError: Maximum call stack size exceeded"

This is my code ( i have tried a lot of things with ViewChild etc, now stuck at this problem ).

import { Component, OnInit, AfterViewInit, Input, ViewChild } 

from '@angular/core';

@Component({
    selector: 'slider',
    template: `
        <div class="slider-container">
            <header>
                <div class="slider-information">
                    <span class="slider-information--title" id="slidername">Acer C720-2103 Chromebook</span>
                    <span class="slider-information--category">
                        Category: <span id="slidercategory">Laptops</span>
                    </span>
                    <span class="slider-information--learnmore">
                        More about <span id="sliderinfoname">Acer C720-2103 Chromebook</span>
                    </span>
                </div>
                <div class="slider-image">
                    <img id="sliderimage" src="../../../images/slider/laptop-slider.jpg" alt="Laptop">
                </div>
            </header>
        </div>
    `,
    styles: [`
        :host{
            overflow: hidden;
        }
    `]
})
export class SliderComponent implements OnInit, AfterViewInit  {
    sliderCount: number = 0;
    images: any[];
    constructor() { }
    ngOnInit() {
        this.images = this.createImages();
    }
    ngAfterViewInit() {
        this.slider();
    }
    slider(): void{
        var slidername = document.getElementById('slidername');
        var sliderimage = document.getElementById('sliderimage');
        var sliderinfoname = document.getElementById('sliderinfoname');
        var slidercategory = document.getElementById('slidercategory');
        if(this.sliderCount > this.images.length - 1){
            this.sliderCount = 0;
        }
        slidername.innerHTML = this.images[this.sliderCount].name;
        sliderimage.setAttribute('src', this.images[this.sliderCount].url);
        sliderinfoname.innerHTML = this.images[this.sliderCount].name;
        slidercategory.innerHTML = this.images[this.sliderCount].category;
        this.sliderCount += 1;
        debugger;
        setTimeout(this.slider(), 2000);
    }
    createImages(): any[]{
        var newImages: any[];
        newImages = [
            { url: "../../../images/slider/laptop-slider.jpg", category: "Laptop" , name: "Acer C720-2103 Chromebook" },
            { url: "../../../images/slider/mobilephone-slider.jpg", category: "Phone", name: "Samsung Edge S6" }
        ]
        return newImages;
    }
}

What is the problem?

UPDATE

I changed this setTimeout(this.slider(), 2000); to setTimeout(this.slider, 2000);. It works only in first iternation. In second i am getting "ERROR TypeError: Cannot read property 'length' of undefined"

  • Keep your question focused on your error message; What kind of debugging have you done to find out why your stack is overflowing? "is my solution good" is not a good question for Stack Overflow because it's too broad and posts should be about one single question so they are useful to others. – Ruan Mendes May 08 '17 at 22:17
  • I was debbugging to find out if text and src were changed ( yes it is, but only on debug mode ). –  May 08 '17 at 22:19
  • Have found the solution, but it made other bug :/ ( update ) –  May 08 '17 at 22:28
  • I recommend you to check the angular 2 docs to see how to make this simpler: https://angular.io/docs/ts/latest/guide/displaying-data.html – Radu Lucut May 08 '17 at 22:33

1 Answers1

0

First you were calling

this.slider() from within this.slider() because you were calling it instead of passing a reference to this.slider, that was causing a stack overflow.

Now you are passing a reference that doesn't have this correctly bound. Change it to

setTimeout(() => this.slider(), 2000);

That will run this.slider() after 2 secs with this correctly set. See How to access the correct `this` context inside a callback?

If you are calling document.getElementById(), you are not doing things as Angular would have you. That data you are digging out of the DOM should be passed to your component instead of tightly coupling your component to the environment.

Community
  • 1
  • 1
Ruan Mendes
  • 90,375
  • 31
  • 153
  • 217