Meal Maker Project (TypeError: Cannot read property ‘appetizers’ of undefined)

Here’s my newest issue. /home/ccuser/workspace/learn-javascript-objects-meal-maker/app.js:36
const dishes = this._course[courseName];
^

TypeError: Cannot read property ‘appetizers’ of undefined
at Object.getRandomDishFromCourse

New code is const menu = { _courses: { appetizers: [], mains: [], desserts: [] }, get appetizers() { return this._courses.appetizers; }, get mains() { return this._courses.mains; }, get desserts() { return this._courses.desserts; }, set appetizers(appetizers){ this._courses.appetizers = appetizers; }, set mains(mains){ this._courses.mains = main; }, set desserts(desserts){ this._courses.desserts = desserts; }, get courses(){ return _courses; }, addDishToCourse (courseName, dishName, dishPrice) { const dish = { name: dishName, price: dishPrice, }; return this._courses[courseName].push(dish) }, getRandomDishFromCourse(courseName) { const dishes = this._course[courseName]; const i = Math.floor(Math.random() * dishes.length); return dishes[i]; }, generateRandomMeal() { const appetizer = this.getRandomDishFromCourse('appetizers'); const main = this.getRandomDishFromCourse('mains'); const dessert = this.getRandomDishFromCourse('desserts'); const totalPrice = appetizer.price + main.price + dessert.price; return You ordered {appetizer.name}, {main.name}, and {dessert.name}. Your total is {totalPrice}.`
},
};
menu.addDishToCourse(‘appetizers’, ‘salad’, 2.50);
menu.addDishToCourse(‘appetizers’, ‘Fries’, 4.50);
menu.addDishToCourse(‘appetizers’, ‘moz sticks’, 3.00);

menu.addDishToCourse(‘mains’, ‘Steak’, 23.00);
menu.addDishToCourse(‘mains’, ‘Chicken’, 12.00);
menu.addDishToCourse(‘mains’, ‘Salmon’, 18.00);

menu.addDishToCourse(‘desserts’, ‘cookies’, 3.00);
menu.addDishToCourse(‘desserts’, ‘cake’, 4.00);
menu.addDishToCourse(‘desserts’, ‘pie’, 3.50);

const meal = menu.generateRandomMeal();
console.log(meal);
`

I think you have a typo here mate:

 generateRandomMeal: () => {

I think that : shouldn’t be there?

Edit: since you are defining an object, that : will mean your generateRandomMeal is being defined as a property, I think?

1 Like

Hello, and welcome to the forums!

This is a little tricky because it involves the scope of this when using an arrow function.

In all the other functions of your object, you are using this style:

nameOfFunction(parameter1, parameter2, etc) {
  ...
}

but you used arrow notation for generateRandomMeal so your calls to this.getRandomDishFromCourse are failing due to the this in that block not being your menu object.

1 Like

It’s funny I just came back to edit the post, the next project reminded me about using .this and arrow function. Still have some bugs to fix. Thank you for the quick feed back!

also maybe you could help me answer another question. In this specific example we are adding new menu items to the _courses object, but within the function that executes this we are using the string ‘appetizers’ but it knows to push these to the appetizers property, which doesn’t use the string data type? I hope that makes sense @irlfede

You might want to look at this: How Do I Format Code In My Posts?

Are you asking how the function to add a dish to the courses object works? You have this code:

addDishToCourse (courseName, dishName, dishPrice) {
   const dish = { 
      name: dishName, 
      price: dishPrice, 
   }; 
   return this._courses[courseName].push(dish)
}

The person that wrote the lesson decided your data would be stored inside an object called courses, with this structure:

_courses: { 
   appetizers: [],
   mains: [],
   desserts: []
}

What you have is the object courses made up of 3 properties appetizers, mains, and desserts. And those properties are themselves defined as empty arrays. If you look back at the definition of the addDishToCourse method, notice that what it does is:

  1. It has three parameters: courseName, dishName, and dishPrice
  2. It packages dishName and dishPrice into yet another object called dish
  3. In the return statement, it uses this._courses[courseName] to access the appropriate property inside the courses object (remember, appetizers, mains, ordesserts) and then uses .push(dish) to add that new dish object into the courses's property. It uses .push() because courses's properties are defined as empty arrays, and this is how we add elements to arrays.