Meal Maker Project - Cannot read property 'push' of undefined

Hi All,

I’m having a few issues on the Meal Maker Project. The link to the project is:

https://www.codecademy.com/courses/introduction-to-javascript/projects/meal-maker

var menu = {
  _courses: {
    appetizers: [],
    mains: [],
    desserts: [],
    get appetizers() {
      return this._courses.appetizers
    },
    set appetizers(appetizerIn) {
      return this._courses.appetizers = appetizers
    },
    get mains() {
      return this._courses.mains
    },
    set mains(mainsIn) {
      return this._courses.mains = mains
    },
    get desserts() {
      return this._courses.desserts
    },
    set desserts(dessertsIn) {
      return this._courses.desserts = desserts
    },
  },
  get _courses() {
    return {
      appetizers: this.appetizers, 
      mains: this.mains,
      desserts: this.desserts
    }
  },
  addDishToCourse(courseName, dishName, dishPrice) {
   var dish = {
     name: dishName,
     price: dishPrice,
    };
    this._courses[courseName].push(dish);
  },
  getRandomDishFromCourse: function(courseName) {
    var dishes = this.courseName;
    var randomIndex = Math.floor(Math.random() * dishes.length);
    return dishes[randomIndex];
  },
  generateRandomMeal: function() {
    var appetizer = this.getRandomDishFromCourse('appetizers');
    var main = this.getRandomDishFromCourse('mains');
    var dessert = this.getRandomDishFromCourse('desserts');
    var cost = appetizer.price + main.price + dessert.price;
    return 'You have ordered ' + appetizer.name + ', ' + main.name + ', and ' + dessert.name + '.' + ' The total cost of the dish is ' + cost 
  }
};

menu.addDishToCourse('appetizers', 'Chicken Salad', 3.74);
menu.addDishToCourse('appetizers', 'Chicken Soup', 2.65);
menu.addDishToCourse('appetizers', 'Egg Salad', 3.21)
menu.addDishToCourse('mains', 'Steak', 9.40);
menu.addDishToCourse('mains', 'Fish Tacos', 8.05);
menu.addDishToCourse('mains', 'Orange Chicken', 7.98);
menu.addDishToCourse('desserts', 'Cheesecake', 5.61);
menu.addDishToCourse('desserts', 'Ice Cream', 4.71);
menu.addDishToCourse('desserts', 'Cake', 5.10);

var meal = menu.generateRandomMeal();
console.log(meal);

The error I’m receiving is:

/home/ccuser/workspace/learn-javascript-objects-meal-maker/app.js:37
this._courses[courseName].push(dish);
^

TypeError: Cannot read property ‘push’ of undefined
at Object.addDishToCourse

Any help with this would be appreciated.

Thanks!

1 Like

Instead of using .push, how about
this[courseName] = dish;

Hi soapyfresh,

Thanks for responding. The whole point of this is to push the new dishes into one of the empty arrays which is why we need the .push() function.

1 Like

the first step would be to figure out where the undefined comes from:

    console.log(this._courses, courseName);
    this._courses[courseName].push(dish);

so there is a problem with the courses object. Which means we narrowed it down.

We declare the properties with array values:

    appetizers: [],
    mains: [],
    desserts: [],

so that is very likely not the problem

So then the problem must be the getters.

the getter of appetizers is part of the courses, object, courses object doesn’t have a courses property like you attempt in the getter.

1 Like

Thank you for your reply. I have spent a long time trying to figure it out but I am still getting the same error. Can you please elaborate?

your other getter:

get _courses() {
    return {
      appetizers: this.appetizers, 
      mains: this.mains,
      desserts: this.desserts
    }
  },

is also off. menu object doesn’t have appetizers property, so doing:

appetizers: this.appetizers, 

this.appetizers will result in undefined.

you could also complete this project without getters and setters first, they don’t add much value.

Also, when using getters, a naming convention is to prefix the property with a underscore, we do this because otherwise we risk recursion:

const myObj = {
  myProp: 0,
  get myProp(){
    return this.myProp;
  }
}

myObj.myProp;

the getter will endlessly call itself, if we prefix the property:

const myObj = {
  _myProp: 0,
  get myProp(){
    return this._myProp;
  }
}

myObj.myProp;

the getter will return the property, not endlessly call itself. Your _courses you get away with it, given you don’t call the courses property.

There are multiple ways to solve the meal maker project. A common one is to add the getters and setters for appetizers, mains and desserts directly to menu object.

then your courses getter calls the getters for appetizers, mains and desserts.