Maximum call stack exceeded error


#1

Hi. I got the maximal code stack whatever error on this code. I can’t see what is wrong. It’s the javascript classes exercise named “Build a library” class Media {
constructor (title) {
this._title = title;
this._isCheckedOut = false;
this._ratings = [];
}
get title () {
return this.title;
}
get _isCheckedOut () {

 return this._isCheckedOut;

}

get ratings () {
return this.ratings;
}
toggleCheckOutStatus () {

this._isCheckedOut = !this._isCheckedOut;
return _isCheckedOut;

}
get AverageRating () {

 let arraySum = function arr () {
   this._ratings.reduce (function (a,b) {
     return a + b;},o);
 }
 let arrayAverage = arraySum/this._ratings.length; 
 return arrayAverage;
 }

addRating (newRating) {
this._ratings.push(newRating);
}
set _isCheckedOut (newValue) {

 if ( this._isCheckedOut == newValue) {
   return true;
 }  else 
   
  {
    _isCheckedOut = newValue;
  }

}
}

class Book extends Media {
constructor (author, title, pages) {
super (title);
super (_isCheckedOut);
super (ratings);
this._author = author;
this._pages = pages;
}
get author () {
return author;
}
get pages () {
return pages;
}
}

class Movies extends Media {
constructor (director, title, runTime) {
super (title);
super (isCheckedOut);
super (ratings);
this._runtime = runTime;
this._director = director;
}
}

const historyOfEverything = new Book (‘Bill Bryson’, ‘A Short History of Nearly Everything’, 544 );

historyOfEverything.toggleCheckOutStatus ();
console.log(historyOfEverything.isCheckedOut);


#2

This may not be the exact problem, but it definitely doesn’t look quite right.

get AverageRating () {

 let arraySum = function arr () {
   this._ratings.reduce (function (a,b) {
     return a + b;},o);
 }
 let arrayAverage = arraySum/this._ratings.length; 
 return arrayAverage;
 }

#3

yes, there was a return missing, however it didn’t solve the problem. it gives the same error for my code’s line nr 10…

How it works

This function is almost identical to the arrSum() function explained above. If you think about it, this makes sense. Finding the average value of a group of numbers is as easy as summing all of the numbers and dividing by the total number of numbers.

In this function, we first use reduce() to reduce all values in our array to a single sum. Once we have the sum we simply divide this value by the length of the array. The result is the average value which then gets returned. from: https://codeburst.io/javascript-arrays-finding-the-minimum-maximum-sum-average-values-f02f1b0ce332


#4

To be more precide, the bootstrap or whatever it is in codecademy thinks, this line below is wrong… : get _isCheckedOut () {

 return this._isCheckedOut;

}


#5

You’re preaching to the choir.

let arrayAverage = arraySum/this._ratings.length; 

What jumps out at us in the above line?

And that is just the half of it.

set _isCheckedOut (newValue) {

 if ( this._isCheckedOut == newValue) {
   return true;
 }  else 
   
  {
    _isCheckedOut = newValue;
  }

}

Definitely something amiss in that code.


#6

To my mind , it should be the average…

However I noticed yesterday, what brings in the case, when code gets me to mess with this loop thing I don’t get at all. That is the following set of lines:

const historyOfEverything = new Book (‘Bill Bryson’, ‘A Short History of Nearly Everything’, 544 );

If I comment it out, there is no error. When I remove the comments and hit save, it says that that there is the specific error I posted above…

I can’t just crasp, what the ■■■■ is wrong, it reaches to line nr 10 and then collapses or crashes or whatever the stack does, when it’s full.


#7

About that if test in the setter: orginally it was like this this._isCheckedOut = newValue;

after initating a new instance of Book class, this gave me a error. I implemented the if test to bypass the error. It worked and that error faded away, reaching to other looping error in line nr 10, still after calling out the Book class with new Book (attributes this and that and so on)


#8

Recall the implementation of getter/setter syntax…

class ClassName {
    constructor (parameter) {
        this._parameter = parameter;
        this._isState = false;
        this._ratings = []
    }
    get parameter () {
        return this._parameter;
    }
    get isState () {
        return this._isState;
    }
    get ratings () {
        return this._ratings;
    }
    set parameter (newParam) {

    }
    set ratings (newRating) {

    }
    toggleState () {
        this._isState = ! this.isState;
    }
}

Every setter requires a getter, but getters do not require setters.

Now I ask, where is the property name _AverageRating?

get AverageRating () {

This getter never runs since there is no property to bind it to. Getters and setters are bound to an attribute by design.

averageRating () {

}

The above is a scaffold for a method.


#9

Yeah, there was issue, it supposed to be a method named : getAverageRating. As my head was full of getters and setters I instead typed: get AvarageRating lol. I fixed this small typo. Code is still showing the same error message.


#10

Sudy the above example for a hint.


#11
class Media {
  constructor (title) {
    this._title = title;
    this._isCheckedOut = false; 
    this._ratings = [];
  }
    get title () {
       return this._title;
    }
   get isCheckedOut () {
     return this._isCheckedOut; 
   }
   get ratings () {
     return this._ratings;
   }
   set isCheckedOut (newValue) {
    this._isCheckedOut = newValue;
   }
   toggleCheckOutStatus () {
     
   this._isCheckedOut = !this._isCheckedOut; //USING IS CHECKEDOUT
     return _isCheckedOut;
     
   }
   getAverageRating () {
  
     let arraySum = function arr () {
       return this._ratings.reduce (function (a,b) {
         return a + b;},0);
     }
     let arrayAverage = arraySum/this._ratings.length; 
     return arrayAverage;
     }
  addRating (newRating) {
    this._ratings.push(newRating);
  }
 
}

class Book extends Media {
  constructor (author, title, pages) {
    super (title);
    super (_isCheckedOut); 
    super (ratings);
    this._author = author;
    this._pages = pages;
  }
   get author () {
     return author;
   }
    get pages () {
      return pages;
    }
}

const historyOfEverything = new Book ('Bill Bryson', 'A Short History of Nearly Everything', 544 );

/home/ccuser/workspace/learn-javascript-classes-build-a-library/app.js:43
super (_isCheckedOut);
^

ReferenceError: _isCheckedOut is not defined
at new Book (/home/ccuser/workspace/learn-javascript-classes-build-a-library/app.js:43:12)
at Object. (/home/ccuser/workspace/learn-javascript-classes-build-a-library/app.js:66:29)
at Module._compile (module.js:571:32)
at Object.Module._extensions…js (module.js:580:10)
at Module.load (module.js:488:32)
at tryModuleLoad (module.js:447:12)
at Function.Module._load (module.js:439:3)
at Module.runMain (module.js:605:10)
at run (bootstrap_node.js:427:7)
at startup (bootstrap_node.js:151:9)


#12

Remove those lines. The toggleState method will act as the setter.

    toggleCheckOutStatus () {     
      this._isCheckedOut = ! this.isCheckedOut;  // uses the getter
    }

#13

/set isCheckedOut (newValue) {
this._isCheckedOut = newValue;
}
/
toggleCheckOutStatus () {

this._isCheckedOut = !this._isCheckedOut; 
 //return _isCheckedOut;

}

class Book extends Media {
constructor (author, title, pages) {
super (title);
super (_isCheckedOut);
super (ratings);
this._author = author;
this._pages = pages;
}

/home/ccuser/workspace/learn-javascript-classes-build-a-library/app.js:43
super (_isCheckedOut);
^

ReferenceError: _isCheckedOut is not defined
at new Book (/home/ccuser/workspace/learn-javascript-classes-build-a-library/app.js:43:12)
at Object. (/home/ccuser/workspace/learn-javascript-classes-build-a-library/app.js:66:29)
at Module._compile (module.js:571:32)
at Object.Module._extensions…js (module.js:580:10)
at Module.load (module.js:488:32)
at tryModuleLoad (module.js:447:12)
at Function.Module._load (module.js:439:3)
at Module.runMain (module.js:605:10)
at run (bootstrap_node.js:427:7)
at startup (bootstrap_node.js:151:9)

Aka book._ischeckedOut is not found/reached/obtained whatever is the right term.


#14

Those two lines may be removed from your Book class.


#15

Ok. Thanks! this solved a problem. Now I am facing another one: ReferenceError: getAverageRating is not defined
at Object.
console.log(getAverageRating(historyOfEverything).toString());

Btw, why does the book class not need the _isCheckedOut and rating thingies?


#16

=> properties

Because it inherits them from the Media class where they are set with initial values. One a boolean, the other an empty array.

As for your other error, repost your completed code up to this point and we’ll see if we can’t suss it out.


#17
class Media {
  constructor (title) {
    this._title = title;
    this._isCheckedOut = false; 
    this._ratings = [];
  }
    get title () {
       return this._title;
    }
   get isCheckedOut () {
     return this._isCheckedOut; 
   }
   get ratings () {
     return this._ratings;
   }
   /*set isCheckedOut (newValue) {
    this._isCheckedOut = newValue;
   }*/
   toggleCheckOutStatus () {
     
    this._isCheckedOut = !this._isCheckedOut; 
     //return _isCheckedOut;
     
   }
   getAverageRating () {
  
     let arraySum = function arr () {
       return this._ratings.reduce (function (a,b) {
         return a + b;},0);
     }
     let arrayAverage = arraySum/this._ratings.length; 
     return arrayAverage;
     }
  addRating (newRating) {
    this._ratings.push(newRating);
  }
 
}

class Book extends Media {
  constructor (author, title, pages) {
    super (title);
    //super (_isCheckedOut); 
   //super (ratings);
    this._author = author;
    this._pages = pages;
  }
   get author () {
     return author;
   }
    get pages () {
      return pages;
    }
}

class Movies extends Media {
  constructor (director, title, runTime) {
    super (title);
    super (isCheckedOut); //USING IS CHECKEDOUT, 
    super (ratings);
    this._runtime = runTime;
    this._director = director;
  }
}

const historyOfEverything = new Book ('Bill Bryson', 'A Short History of Nearly Everything', 544 );

historyOfEverything.toggleCheckOutStatus (); 
console.log(historyOfEverything.isCheckedOut); 

console.log(getAverageRating(historyOfEverything).toString());
const speed = new Movie ('Jan de Bont', 'Speed', '116');
speed.toggleCheckOutStatus();
console.log(speed._isCheckedOut);
speed.addRating(1);
speed.addRating(1);
speed.addRating(5);
speed.getAveragerating();
console.log(speed.getAveragerating());

#18

Those lines are not needed/ They are declared and initialized in the parent class.

That method should be outside of the getAverageRating method.

The method takes no argument, and it needs a context.

console.log(historyOfEverything.getAverageRating().toString());

The method itself still contains some errors.

  let arraySum = function arr () {
      return this._ratings.reduce (function (a,b) {
        return a + b;},0);
    }

You are declaring it as a function when it doesn’t need to be one.

    let arraySum = this.ratings.reduce (function (a,b) {
        return a + b;
    });

which will fix the error in this line…

You have a getter for ratings so may as well use it as I did above.

This method can use the setter for ratings.

  addRating (newRating) {
    this.ratings = newRating;
  }

Oh, wait… The setter is missing.

  set ratings (newRating) {
    this.ratings.push(newRating);
  }

In you commands there are some errors as well.

If you don’t give historyOfEverything any new ratings the getAvrageRating method will return NaN.

I mentioned the error about context, above.

Use the getter.

Note the spelling errors above.

I think the intention was to call the class Movie but you have it as Movies.


#19

Thanks for the help! I got some of the code working… It logs true, meaning it reaches to isCheckedOut attribute of the book class.Then it reaches to getAverageRating function declaring the result as NaN aka not a number. After that it throws an error on me. It gices the same results for the movie. I don’t know what’s wrong with the getAverageRating fuction. Anyways here is the code:

class Media {
  constructor (title) {
    this._title = title;
    this._isCheckedOut = false; 
    this._ratings = [];
  }
    get title () {
       return this._title;
    }
   get isCheckedOut () {
     return this._isCheckedOut; 
   }
   get ratings () {
     return this._ratings;
   }
  
   toggleCheckOutStatus () {
     
    this._isCheckedOut = !this._isCheckedOut; 
   }
  set ratings (newRating) {
    this.ratings.push(newRating);
  }
   getAverageRating () {
  
     let arraySum = function arr () {
       return this._ratings.reduce (function (a,b) {
         return a + b;});
     }
     let arrayAverage = arraySum/this._ratings.length; 
     return arrayAverage;
     }
  addRating (newRating) {
    this._ratings.push(newRating);
  }
 
}

class Book extends Media {
  constructor (author, title, pages) {
    super (title);
    //super (_isCheckedOut); 
   //super (ratings);
    this._author = author;
    this._pages = pages;
  }
   get author () {
     return author;
   }
    get pages () {
      return pages;
    }
}

class Movies extends Media {
  constructor (director, title, runTime) {
    super (title);
   
    this._runtime = runTime;
    this._director = director;
  }
}

const historyOfEverything = new Book ('Bill Bryson', 'A Short History of Nearly Everything', 544 );

historyOfEverything.toggleCheckOutStatus (); 
console.log(historyOfEverything.isCheckedOut); // ok, console logs true
historyOfEverything.addRating(4);
historyOfEverything.addRating(5);
historyOfEverything.addRating(5);
console.log(historyOfEverything.getAverageRating());
const speed = new Movies ('Jan de Bont', 'Speed', '116');
speed.toggleCheckOutStatus();
console.log(speed._isCheckedOut);
speed.addRating(1);
speed.addRating(1);
speed.addRating(5);
speed.getAverageRating();
console.log(speed.getAverageRating());

#20

I got some technical questions. Like how do I know what do I need to declare in subclass/child class and what not to declare in it? As we had this isCheckedOut and ratings issue that I thought I needed to declare them in my sub class, though actually i didnt need to.

How to understand the meaning or function of this setter thing in here?