Meal Maker - Undefined Price


#1

Would someone be so kind as to point me in the right direction what I am doing wrong here?
I am struggling hard with this lol

//Menu Object
const menu = {
  _courses: {
    appetizers: [],
    mains: [],
    desserts: [],
  },
  get appetizers() {
		return this.appetizers
  },
  set appetizers(appetizerIn) {
		this.appetizers = appetizerIn
  },
  get mains() {
		return this.mains
  },
  set mains(mainIn) {
		this.mains = mainsIn
  },
  get desserts() {
		return this.desserts
  },
  set desserts(dessertIn) {
		this.desserts = dessertIn
  },
	get courses() {
    return {
      appetizers: this._courses.appetizers,  // this uses the appetizer getter method
      mains: this._courses.mains,  // this uses the main getter method
      desserts: this._courses.desserts,  // this uses the dessert getter method
    }
  },
  //----------------
  addDishToCourse (courseName, dishName, dishPrice) {
    const dish = {
      name: dishName,
      price: dishPrice
    };
      
    this._courses[courseName].push(dish); // also try using your setter method!
  },
  getRandomDishFromCourse (courseName) {
    const dishes = this._courses[courseName];
    const randomIndex = Math.floor(Math.random() * dishes.length);
    // return a dish from `dishes` by using `randomIndex`
  },
  generateRandomMeal: function() {
    const appetizer = this.getRandomDishFromCourse('appetizers');
    const mains = this.getRandomDishFromCourse('mains');
    const desserts = this.getRandomDishFromCourse('desserts');
    const totalPrice = appetizer.price + main.price + dessert.price;

    return `Your meal is ${appetizer.name}, ${main.name}, ${dessert.name}, The price is $${totalPrice}.`;
  }
};
menu.addDishToCourse('appetizers', 'Caesar Salad', 4.25);
menu.addDishToCourse('appetizers', 'Spring Rolls', 5.25);
menu.addDishToCourse('appetizers', 'Chef Salad', 3.75);
menu.addDishToCourse('mains', 'Fried Chicken and Poutine', 14.25);
menu.addDishToCourse('mains', 'Prawn Pasta', 13.75);
menu.addDishToCourse('mains', 'Pork Ramen', 11.50);
menu.addDishToCourse('desserts', 'Chocolate Torte', 3.75);
menu.addDishToCourse('desserts', 'Frozen Yogurt', 3.75);
menu.addDishToCourse('desserts', 'Berry Sorbet', 3.75);

let meal = menu.generateRandomMeal();
console.log(meal);
/home/ccuser/workspace/learn-javascript-objects-meal-maker/app.js:51
    const totalPrice = appetizer.price + main.price + dessert.price;
                                ^

TypeError: Cannot read property 'price' of undefined
    at Object.generateRandomMeal (/home/ccuser/workspace/learn-javascript-objects-meal-maker/app.js:51:33)
    at Object.<anonymous> (/home/ccuser/workspace/learn-javascript-objects-meal-maker/app.js:66:17)
    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)

https://www.codecademy.com/paths/web-development/tracks/web-dev-js-arrays-loops-objects/modules/learn-javascript-objects/projects/meal-maker

I would greatly appreciate the help.
Also if anyone has any tips on resources to help make these core JavaScript principles sink in you will have a friend for life lol

Regards,
Colton


#2

Update

From reviewing other peoples solution I was able to isolate what section the error was coming from. I am struggling with concepts in this exercise and need to practice logging things to console as I go to ensure each section is doing what I expect.

I needed to return a dish from dishes by using randomIndex

getRandomDishFromCourse: function (courseName) {
    const dishes = this._courses[courseName];
    const randomIndex = Math.floor(Math.random() * dishes.length);
    return dishes[randomIndex];// return a dish from `dishes` by using `randomIndex`
  },

This then gave me an error on the price for mains so I tried taking the ‘s’ off ‘mains’ and ‘desserts’

generateRandomMeal: function() {
    const appetizer = this.getRandomDishFromCourse('appetizers');
    const main = this.getRandomDishFromCourse('mains');
    const dessert = this.getRandomDishFromCourse('desserts');
    const totalPrice = appetizer.price + main.price + dessert.price;

    return `Your meal is ${appetizer.name}, ${main.name}, ${dessert.name}, The price is $${totalPrice}.`;
  }

Voila

Still not 100% on how this all goes together but hopefully with some review I will start to get a better grasp of this.

My Solution:

//Menu Object
const menu = {
  _courses: {
    appetizers: [],
    mains: [],
    desserts: [],
  },
    get appetizers() {
      return this.appetizers;
  },
    set appetizers(appetizerIn) {
      this._courses.appetizers = appetizerIn;
  },
    get mains() {
      return this.mains;
  },
    set mains(mainIn) {
      this._courses.mains = mainIn;
  },
    get desserts() {
      return this.desserts;
  }, 
    set desserts(dessertIn) {
      this._courses.desserts = dessertIn;
  },
	get courses() {
    return {
      appetizers: this._courses.appetizers,  // this uses the appetizer getter method
      mains: this._courses.mains,  // this uses the main getter method
      desserts: this._courses.desserts,  // this uses the dessert getter method
    }
  },
  //----------------
  addDishToCourse (courseName, dishName, dishPrice) {
    const dish = {
      name: dishName,
      price: dishPrice,
    };
      
    this._courses[courseName].push(dish); // also try using your setter method!
  },
  
  getRandomDishFromCourse: function (courseName) {
    const dishes = this._courses[courseName];
    const randomIndex = Math.floor(Math.random() * dishes.length);
    return dishes[randomIndex];// return a dish from `dishes` by using `randomIndex`
  },
  generateRandomMeal: function() {
    const appetizer = this.getRandomDishFromCourse('appetizers');
    const main = this.getRandomDishFromCourse('mains');
    const dessert = this.getRandomDishFromCourse('desserts');
    const totalPrice = appetizer.price + main.price + dessert.price;

    return `Your meal is ${appetizer.name}, ${main.name}, ${dessert.name}, The price is $${totalPrice}.`;
  }
};
menu.addDishToCourse('appetizers', 'Caesar Salad', 4.25);
menu.addDishToCourse('appetizers', 'Spring Rolls', 5.25);
menu.addDishToCourse('appetizers', 'Chef Salad', 3.75);
menu.addDishToCourse('mains', 'Fried Chicken and Poutine', 14.25);
menu.addDishToCourse('mains', 'Prawn Pasta', 13.75);
menu.addDishToCourse('mains', 'Pork Ramen', 11.50);
menu.addDishToCourse('desserts', 'Chocolate Torte', 3.75);
menu.addDishToCourse('desserts', 'Frozen Yogurt', 3.75);
menu.addDishToCourse('desserts', 'Berry Sorbet', 3.75);

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

#3

The above is a circular reference. Use the backing variable name.

return this._appetizers;

this._appetizers = appetizerIn;

Same applies to the other getters and setters. That will need to be fixed before anything.

That is old syntax. Use the ES6 method syntax, like the others.

method () {

}