Meal Maker Project TypeError - Objects

Hi, I hope someone can explain what the problem is, as I am struggling to understand this.

Here is a link to my code in the JS Objects Meal Maker Project.

I have both used the hints and watched the video walk through for this project, and can’t see what I am doing differently to them (the video and hints had some differences to each other, but I tried following each way) - yet I am getting an error.

TypeError Message:

/home/ccuser/workspace/learn-javascript-objects-meal-maker/app.js:42
this._courses[courseName].push(dish);
^
TypeError: Cannot read property ‘push’ of undefined
at Object.addDishToCourse (/home/ccuser/workspace/learn-javascript-objects-meal-maker/app.js:42:29)
at Object. (/home/ccuser/workspace/learn-javascript-objects-meal-maker/app.js:65:6)
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)

My code:

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 = mains;
  },
  set desserts(desserts) {
    this._courses.desserts = desserts;
  },
  
  get courses() {
    return {
     appetizers: this.appetizers, 
     mains: this.mains,
     desserts: this.desserts
    }
  },

  addDishToCourse (courseName, dishName, dishPrice) { 
    const dish = {
      name: dishName,
      price: dishPrice,
  };

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

  getRandomDishFromCourse(courseName) {
    const dishes = this._courses[courseName];
    const random = Math.floor(Math.random() * dishes.length);
    return dishes[random];
  },

  generateRandomMeal() {
    const appetizer = getRandomDishFromCourse("appetizers");
    const main = getRandomDishFromCourse("mains");
    const dessert = getRandomDishFromCourse("desserts");
    const totalPrice = appetizer.price + main.price + dessert.price;

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

};

menu.addDishToCourse('appetizers', 'Caesar Salad', 4.25);
menu.addDishToCourse('appetizers', 'Garlic Bread', 5.75);
menu.addDishToCourse('appetizers', 'Dip', 2.15);
menu.addDishToCourse('main', 'Lasagne', 11.00);
menu.addDishToCourse('main', 'Steak', 15.25);
menu.addDishToCourse('main', 'Tacos', 12.95);
menu.addDishToCourse('dessert', 'Yoghurt', 4.25);
menu.addDishToCourse('dessert', 'Cheesecake', 7.25);
menu.addDishToCourse('dessert', 'Chocolate', 6.25);

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

nicely done to include both your code and the exercise url, too few people do this. Thank you :slight_smile:

The first I would take to debug this problem is to look at the available keys and the key you attempt to use:

  addDishToCourse (courseName, dishName, dishPrice) { 
    const dish = {
      name: dishName,
      price: dishPrice,
  };

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

I include a .log() to inspect your code, as you can see, you use 'main' at some point, while the key/property is 'mains'

Personally, I think JavaScript could throw a better error earlier. An error like: property 'main' does not exist on object is so much easier to understand/debug then failing silently (giving undefined)

not sure if Object.keys() has been introduced yet, but that gives us all the keys off an object.

1 Like

Thanks for your reply stetim94, that has certainly helped me solve one of the problems with my code, and given me a better understanding about how to go about inspecting my code for problems.

After receiving your advice, I have made corrections to the course keys, spent many more hours trying to use .log() to identify my problem, including using VSCode & the terminal as an alternative to Codecademy’s console, tried different potential solutions, and have rewatched the video walk through again - however unfortunately I am still getting an error I can’t understand, and can’t see what I am doing differently to the video walk through.

Many thanks for your patience, and thanks in advance for any more help you might be able to give.

Here is the current error message… so it doesn’t accept that the getRandomDishFromCourse function has been defined.

/home/ccuser/workspace/learn-javascript-objects-meal-maker/app.js:52
    const appetizer = getRandomDishFromCourse('appetizers');
                      ^

ReferenceError: getRandomDishFromCourse is not defined
    at Object.generateRandomMeal (/home/ccuser/workspace/learn-javascript-objects-meal-maker/app.js:52:23)
    at Object.<anonymous> (/home/ccuser/workspace/learn-javascript-objects-meal-maker/app.js:71:19)
    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)

Most recent code

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 = mains;
  },
  set desserts(desserts) {
    this._courses.desserts = desserts;
  },

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

  addDishToCourse(courseName, dishName, dishPrice) {
    const dish = {
      name: dishName,
      price: dishPrice,
    };

    return this._courses[courseName].push(dish);
  },

  getRandomDishFromCourse(courseName) {
    const dishes = this._courses[courseName];
    const randomIndex = Math.floor(Math.random() * dishes.length);
    return dishes[randomIndex];
  },

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

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

menu.addDishToCourse('appetizers', 'Caesar Salad', 4.25);
menu.addDishToCourse('appetizers', 'Garlic Bread', 5.75);
menu.addDishToCourse('appetizers', 'Dip', 2.15);
menu.addDishToCourse('mains', 'Lasagne', 11.0);
menu.addDishToCourse('mains', 'Steak', 15.25);
menu.addDishToCourse('mains', 'Tacos', 12.95);
menu.addDishToCourse('desserts', 'Yoghurt', 4.25);
menu.addDishToCourse('desserts', 'Cheesecake', 7.25);
menu.addDishToCourse('desserts', 'Chocolate', 6.25);

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

That is actually really good :slight_smile: That is the right attitude towards (for?) programming :slight_smile:

getRandomDishFromCourse is not a function, its a method/property of menu object.

To access properties, you need this (which is the current object), so then you get:

this.getRandomDishFromCourse('appetizers');
1 Like

OMG I must be going blind! I can’t believe I didn’t see that. Plus, obviously, I need to work more on this material because I have a pretty fuzzy understanding of it - still getting my head around this, methods vs functions, and so on.

Thank you so much for your help stetim94, it’s so good to have a second set of eyes AND someone who actually knows what they’re doing! You’ve really helped me out here, I’m so grateful.

1 Like