Building a library - Push Error


#1

Hi Community!

I’m working on the Build a Library project and I’m having some trouble with the .push(ratings) section.

I think the rest of the code is good (correct me if it needs to be cleaned up) but I can’t figure out how to fix the push error. The error I get says: “TypeError: Cannot read property ‘push’ of undefined
at Book.addRating”

Here is my code

//------- parent Media class ---------//
class Media {
  constructor(title) {
    this._title = title;
    this._isCheckedOut = false;
    this._ratings;
  }
 //------- parent Getter for title -----//
  get title () {
    return this._title;
  }
  //------- parent Getter for isCheckedOut -----//
  get isCheckedOut () {
    return this._isCheckedOut;
  }
  //------- parent Getter for ratings -----//
  get ratings () {
    return this._ratings;
  }
  //------- parent Setter for isCheckedOut -----//
  set isCheckedOut (checkOut) {
    this._iscCheckedOut = checkOut;
  }
  //---------- method to change the value of is Checked Out---------//
 toggleCheckOutStatus () {
    this._isCheckedOut = !this._isCheckedOut;
  }
//--------method to get the Average rating ---- //
//---- We the used the reduce method and saved it to ratings. Then we the number of ratings and put it into lengthArray. We then created a new variable called average and divided the sum by the number of reviews. Then set ratings equal to the variable average. -------//  
  getAverageRating (){
   let ratingsSum = this.ratings.reduce((currentSum, rating) => currentSum + rating, 0);
   let lengthArray = this._ratings.length;
   let average = Math.round(ratingsSum / lengthArray);
    this._ratings = average;
  }
//------- Method to add rating ------//
  addRating (ratings) {
    this._ratings.push(ratings)
  }
}
//-------- creating book class that takes in properties from parent Media class-------//
class Book extends Media {
  constructor (author, title, pages){
    super(title);
    this._author = author;
    this._pages;
  }
//-------- getter for author ---------//  
  get author () {
    return this._author;
  }
//--------- getter for pages -----------//
  get pages () {
    return this._pages;
  }
}

//-------- creating movie class that takes in properties from parent Media class ---------//
class Movie extends Media {
  constructor (director, title, runTime) {
    super(title);
    this._director = director;
    this._runTime;
  }
//------- getter for director ----------//
  get director () {
    return this._director;
  }
//-------- getter for runTime ----------//
  get runTime () {
    return this._director;
  }
}
//-------- creating a new Book instance ---------//
const historyOfEverything = new Book('Bill Bryson', 'A Short History of Nearly Everything', 544);
//---- calling toggleCheckOutStatus to change it to true -------//
historyOfEverything.toggleCheckOutStatus ();
console.log(historyOfEverything.isCheckedOut);
//------- adding 3 ratings to the book, getting the average rating, and logging it ------------//
historyOfEverything.addRating(4);
historyOfEverything.addRating(5);
historyOfEverything.addRating(5);
historyOfEverything.getAverageRating();
console.log(historyOfEverything.getAverageRating);

//------- creating a movie instance --------//
const speed = new Movie ('Jan de Bont', 'Speed', 116);
//---- calling toggleCheckOutStatus to change it to true -------//
speed.toggleCheckOutStatus();
console.log(speed.isCheckedOut);
//------- adding 3 ratings to the Movie, getting the average rating, and logging it ------------//
speed.addRating(1);
speed.addRating(1);
speed.addRating(5);
speed.getAverageRating();
console.log(speed.getAverageRating);

#2

in the Media constructor you have this line:

this._ratings;

given you don’t give it a value, JavaScript has to give it a value, which will be undefined

undefined doesn’t have a push method, maybe you should make ratings an array?


#3

Aww thank you for the help. I also found some other errors in the code as well. Here is the updated code. I added Math.round() on the getAverageRating function.

//------- parent Media class ---------//
class Media {
  constructor(title) {
    this._title = title;
    this._isCheckedOut = false;
    this._ratings = [ ];
  }
 //------- parent Getter for title -----//
  get title () {
    return this._title;
  }
  //------- parent Getter for isCheckedOut -----//
  get isCheckedOut () {
    return this._isCheckedOut;
  }
  //------- parent Getter for ratings -----//
  get ratings () {
    return this._ratings;
  }
  //------- parent Setter for isCheckedOut -----//
  set isCheckedOut (checkOut) {
    this._iscCheckedOut = checkOut;
  }
  //---------- method to change the value of is Checked Out---------//
 toggleCheckOutStatus () {
    this._isCheckedOut = !this._isCheckedOut;
  }
//--------method to get the Average rating ---- //
//---- We the used the reduce method and saved it to ratings. Then we the number of ratings and put it into lengthArray. We then created a new variable called average and divided the sum by the number of reviews. Then set ratings equal to the variable average. -------//  
 /* --------old code that wasn't working. Got rid of it for new code located below. -------//
 
 getAverageRating (){
   let ratingsSum = this.ratings.reduce((currentSum, rating) => currentSum + rating, 0);
   let lengthArray = this._ratings.length;
   let average = Math.round(ratingsSum / lengthArray);
    this._ratings = average;
  }*/
  
   getAverageRating() {
    let ratingsSum = this.ratings.reduce((currentSum, rating) => currentSum + rating, 0);
    //--- returning the value now-----//
     return Math.round(ratingsSum/this.ratings.length)
  }

//------- Method to add rating ------//
  addRating (ratings) {
    this._ratings.push(ratings)
  }
}
//-------- creating book class that takes in properties from parent Media class-------//
class Book extends Media {
  constructor (author, title, pages){
    super(title);
    this._author = author;
    this._pages;
  }
//-------- getter for author ---------//  
  get author () {
    return this._author;
  }
//--------- getter for pages -----------//
  get pages () {
    return this._pages;
  }
}

//-------- creating movie class that takes in properties from parent Media class ---------//
class Movie extends Media {
  constructor (director, title, runTime) {
    super(title);
    this._director = director;
    this._runTime;
  }
//------- getter for director ----------//
  get director () {
    return this._director;
  }
//-------- getter for runTime ----------//
  get runTime () {
    return this._director;
  }
}
//-------- creating a new Book instance ---------//
const historyOfEverything = new Book('Bill Bryson', 'A Short History of Nearly Everything', 544);
//---- calling toggleCheckOutStatus to change it to true -------//
historyOfEverything.toggleCheckOutStatus ();
console.log(historyOfEverything.isCheckedOut);
//------- adding 3 ratings to the book, getting the average rating, and logging it ------------//
historyOfEverything.addRating(4);
historyOfEverything.addRating(5);
historyOfEverything.addRating(5);
historyOfEverything.getAverageRating();
console.log(historyOfEverything.getAverageRating());

//------- creating a movie instance --------//
const speed = new Movie ('Jan de Bont', 'Speed', 116);
//---- calling toggleCheckOutStatus to change it to true -------//
speed.toggleCheckOutStatus();
console.log(speed.isCheckedOut);
//------- adding 3 ratings to the Movie, getting the average rating, and logging it ------------//
speed.addRating(1);
speed.addRating(1);
speed.addRating(5);
speed.getAverageRating();
console.log(speed.getAverageRating());