0

I can not understand why "Uncaught RangeError: Maximum call stack size exceeded" appears. I am trying to solve:

The problem:

Create an object Polygon for instantiating a new Polygon that will output to the console a text based on how many segments the polygon is composed by. The polygon has one property segments that stores this value and can be accessed via its getSegments() function.

By default it has 3 segments.

If the segments are strictly less than 3, Polygon will set them to 3 and log an error saying "A polygon need to have 3 segments, it will be set to 3".

The cases are:

1. If segments are undefined the polygon name is triangle
2. If segments are <3 the polygon name is set to triangle
3. If segments are 3 the polygon name is set to triangle
4. If segments are 4 the polygon name is set to quadrilateral
5. If segments are 5 the polygon name is set to pentagon
6. If segments are 6 the polygon name is set to hexagon

What I tried to do?

I tried creating class Polygon and then function getSegments(segments) to change the segments property of the new object depending on the segments prop to be passed along the conditionals, and in the situation where i am calling the script externally from index.html page, it works. But when I try to paste the code into browser console, and in the Node.js environment i am getting "Uncaught RangeError: Maximum call stack size exceeded" error. I haven't encountered this kind of error before, so if anybody could see what I did wrong there, or know how to explain to me how to avoid that in the future, I would very much be grateful.

class Polygon {
    constructor () {
        this.segments = getSegments();
    }
}

function getSegments(segments) {
    this.segments = segments;
    if (segments < 3) {
        polygon = new Polygon(segments)
        console.log ('A polygon need to have at least 3 
segments. It will be set to 3.')
        polygon.segments = 3
    } else if (segments === 3) {
        polygon = new Polygon(segments)
        console.log ('The polygon name is triangle')
    } else if (segments === 4) {
        polygon = new Polygon(segments)
        console.log ('The polygon name is quadrilateral')
    } else if (segments === 5) {
        polygon = new Polygon(segments)
        console.log ('The polygon name is pentagon')
    } else if (segments === 6) {
        polygon = new Polygon(segments)
        console.log ('The polygon name is hexagon')
    } else if (typeof segments == 'undefined') {
        polygon = new Polygon(3)
        console.log ('The polygon name is triangle')
    }
}

Results:

I expected output like:

getSegments(4) //-> polygon object with segments property, it's value 4 and console.log text The polygon name is quadrilateral.

Actual output instead is: Uncaught RangeError: Maximum call stack size exceeded.

Thank you in advance for all your advice's and help.

Solution

Actually problem was in this block of code:

`class Polygon {
        constructor () {
            this.segments = getSegments();
        }
    }`

line of code that needs to be replaced is:

`this.segments = segments`and with constructor we need to pass segments like this `constructor (segments)`, and the error is resolved.
Srki
  • 51
  • 2
  • 8
  • 1
    Possible duplicate of [Maximum call stack size exceeded error](https://stackoverflow.com/questions/6095530/maximum-call-stack-size-exceeded-error) – Kody R. Jan 05 '19 at 20:38
  • 5
    When you call `getSegments()` it calls `new Polygon()` which calls `getSegments()` which calls `new Polygon()`... – Mark Jan 05 '19 at 20:43
  • @Kody R. saw that one and bunch of others similar, but haven't been able to use them as a example and in relation to my specific case scenario. I haven't been able to understand how they can be applied to this specific scenario in my case. – Srki Jan 05 '19 at 20:43
  • @MarkMeyer Do you have any suggestion how would I avoid to do that and still keep the task demands intact ? – Srki Jan 05 '19 at 20:46
  • 2
    `Uncaught RangeError: Maximum call stack size exceeded` will almost always happen because you're recursively calling methods inside other methods. You're also not passing in any segments in your getSegments()' call – Kody R. Jan 05 '19 at 20:51
  • @MarkMeyer P.S. you in fact helped me a lot, by pushing me slighter in the right direction. I found a solution, thanks to you. You helped a lot. – Srki Jan 05 '19 at 20:53
  • Why does your `getSegments` function call `new Polygon` at all? By the way, you're not supposed to call `getSegments` from your `Polygon` constructor; `getSegments` is supposed to be a method of polygon objects. – melpomene Jan 05 '19 at 20:53
  • @Kody R. indeed you were halpful too, and you are maybe right now when I look at possible duplicate, but there are not specific like this case of mine, so I will leave it for someone else to find a solution and maybe solve his problem. Thank you for your help to mister Kody. – Srki Jan 05 '19 at 20:55
  • 1
    The issue is the loop you are creating. As mark meyer stated. But oop speaking, loop aside, your classes don't make sense. A polygon is a set of edges/segments, not of other polygons. You should need to introduce another class for manipulating segments too, again, oop speaking. – quirimmo Jan 05 '19 at 20:56
  • @quirimmo you are right OOP speaking, I haven't thought of that in a rush, I will try to take that approach too. Thanks. – Srki Jan 05 '19 at 21:05

1 Answers1

1

You should decide whether you will create a Polygon and then figure out the segments, or whether getsegments will be a factory that makes Polygon instances. Doing both leads to an infinite cycle.

Here's one idea that simplifies things by having a method on the Polygon class. Then you can call it in the constructor to setup the polygon instance:

let types = ['triangle', 'quadrilateral', 'pentagon', 'hexagon']

class Polygon {
    constructor (n) {
         // call instance method that will set type
         // an hanlde out of range segment
        this.setType(n)
    }
    setType(segments) {
        // handle bad segment lengths
        if (!segments || segments < 3) {  
            console.log ('A polygon need to have at least 3 segments. It will be set to 3.')
            segments = 3
        }
        if (segments > 6){
            console.log("Unknown polygon, setting segments to 6")
            segments = 6
        }
        // setProps
        // array index starts at zero; subtract three to make 
        // segments of 3 map to array index 0 
        this.type = types[segments - 3]
        this.segments = segments
    }
}


console.log(new Polygon(2))
console.log(new Polygon(3))
console.log(new Polygon(4))
console.log(new Polygon(5))
console.log(new Polygon(6))
console.log(new Polygon(7))
Mark
  • 90,562
  • 7
  • 108
  • 148
  • 1
    let me tell you this a hell of an idea, much simplified, and very interesting with array and setting props, I like this your much better than mine. Well done and thank you for your thoughts and creativity. – Srki Jan 05 '19 at 21:13
  • I am just thinking, my concentration is little low, and I have a dillema what actually you are doing with this line in the setting props `this.type = types[segments - 3]` I understand that you are affecting with this object Polygon and setting the property but i have a dilemma how do you affecting the array with `[segments - 3]`. ? – Srki Jan 05 '19 at 21:24
  • @Srki array indexing starts at zero, but the lowest segment is three. `segments -3` makes the triangle = 0, which is the index for the triangle. You could also use an object with keys like `{3: 'triangle'}` then you wouldn't need the subtraction. – Mark Jan 05 '19 at 21:26
  • you missed a giant AHA moment here, it makes sense, i was thinking something like that but I completely forgot, when the segment is 1 or 2 it is in fact three, then it makes sense all the way. I owe you a giant Beer here when you come in Belgrade, Serbia for keeping up with my fatigue and lack of thoughts. Thank you! – Srki Jan 05 '19 at 21:32