Meal maker error

I’ve been working on the meal maker and I keep getting an error message.

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 dishs = this._courses[courseName];

  const randomIndex = Math.floor(Math.random() * dishes.length);

  return dishes[randomIndex];

},

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 `Your meal is ${appetizer.name}, ${main.name}, and ${dessert.name}, and the total price is ${totalPrice}`;

  }

};

menu.addDishToCourse('appetizers', 'salad', 4.00);

menu.addDishToCourse('appetizers', 'bread', 2.50);

menu.addDishToCourse('appetizers', 'olives', 4.50);

menu.addDishToCourse('mains', 'Burger', 8.00);

menu.addDishToCourse('mains', 'steak', 10.00);

menu.addDishToCourse('mains', 'tofu', 5.00);

menu.addDishToCourse('dessert', 'ice cream', 3.00);

menu.addDishToCourse('dessert', 'sticky toffee pudding', 5.00);

menu.addDishToCourse('appetizers', 'cake', 7.00);

const meal = menu.generateRandomMeal();

Console.log(meal);
1 Like

and I keep getting this error but I can’t find out what is wrong.

/home/ccuser/workspace/learn-javascript-objects-meal-maker/app.js:37
return 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:37:40)
at Object. (/home/ccuser/workspace/learn-javascript-objects-meal-maker/app.js:61: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)

Hi,

Would love to help, can you re-highlight your text and press the </> button, write now it’s only formatting some of your code.

The error message is basically saying that this._courses[courseName] is undefined when you write the following: this._courses[courseName].push(dish);. You have to trace your code and see where it goes wrong (console.log statements help)

You also have at least one spelling mistake in your code.

HI,

I’ve been following the expert video step by step so it should be right.

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 dishs = this._courses[courseName];
  const randomIndex = Math.floor(Math.random() * dishes.length);
  return dishes[randomIndex];
},
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 `Your meal is ${appetizer.name}, ${main.name}, and ${dessert.name}, and the total price is ${totalPrice}`;
  },
};

menu.addDishToCourse('appetizers', 'salad', 4.00);
menu.addDishToCourse('appetizers', 'bread', 2.50);
menu.addDishToCourse('appetizers', 'olives', 4.50);

menu.addDishToCourse('mains', 'Burger', 8.00);
menu.addDishToCourse('mains', 'steak', 10.00);
menu.addDishToCourse('mains', 'tofu', 5.00);

menu.addDishToCourse('dessert', 'ice cream', 3.00);
menu.addDishToCourse('dessert', 'sticky toffee pudding', 5.00);
menu.addDishToCourse('appetizers', 'cake', 7.00);

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

What does this line of code do? What is menu? What is addDishToCourse? What are 'dessert', 'ice cream', 3.00?

Understanding what your code does is key. What your code is supposed to do, or, rather, what you want it to do versus what it actually does is only a mystery until you look. You can observe what input is provided to a function by inserting console.log() statements as suggested by @toastedpitabread. You can also observe what happens to that input after each step within the function.

That is the whole point of me asking on this forum. I have looked and I do not understand and therefore have asked for help. Saying that I need to look at the code does not help me. Telling me to input console.log() statements does not help me particularly if I am struggling to understand JavaScript in the first place and knowing when to used anything is still a mystery to me. If I follow the expert video and nothing happens then what is the point in having the videos is the first place.

@dendroman

The point of console.log() is to be a tool for us to understand what is unclear.

For me personally, I cannot follow code from a video unless I know for certain what it does (at least on a superficial level), so if I’m following a tutorial and I don’t understand something, I’ll stop and play around with the new code that was written.

The point of the code is not necessarily “right”, but for us to have control over what it does. In practical applications, that means that when we need the code to do something slightly different we can tweak it accordingly. If I personally am overwhelmed by the code I’m working on at the moment (it happens), I will break it apart and practice working on just segments of this to better understand the mechanics at work. It’s a skill of the trade.

In these forums we don’t provide straight-up answers (it’s the policy) but everyone is very friendly in providing tips to highlight potential ways to arrive at the answer. If you the comments aren’t helpful, you can try asking it in a different way as to what a particular problem is and maybe that’ll elicit a different type of reply.

Which of the questions I posed, do you not know the answer to? That would be a place to start.
If it’s all of them, fine. We can start explaining wherever necessary. The goal here, at least my goal, is to help you learn and understand JavaScript. The goal is not to simply mark a task as complete, and move on. If that were the goal, I’d just tell you exactly what to change.

If you could explain everything that you mention that would be amazing. I feel that I am tearing my hair out with the JavaScript course half the time.

Well, let’s start with menu.

menu is an object. It has properties and methods. In this case, menu only has a single property. That property happens to also be an object that has 3 additional properties. Object properties are key: value pairs. You can research JavaScript objects here.

So, menu has a single property called _courses. The value _courses is assigned to is an object. That object has 3 properties called appetizers, mains and desserts. The values each of those keys are assigned to are empty arrays. We see that here:

If we left out all of the methods for now, our complete menu object would look like this:

const menu = {
  _courses: {
    appetizers:[],
    mains: [],
    desserts: []
  }
}

We could simply modify the objects with code if we wanted, but since we will be repeating the same actions again and again, it makes sense to add methods to the menu object that can be reused. To use an object’s method we call it like so, objectName.methodName(arguments). In your code, you have a method named, addDishToCourse. The method takes 3 parameters, so we call the method with 3 arguments like you show here:

Next, we need to look at what the method does.

So, we create a dish object giving it 2 key: value pairs (properties). The keys are name and price, the values are the arguments passed from the method call that the parameters are now assigned to. Using the example above, dishName is assigned to 'salad', and dishPrice is assigned to 4.00.
We can use console.log() to verify this:

  addDishToCourse(courseName, dishName, dishPrice){
   //Create an object called dish with 2 properties
   console.log(`courseName: ${courseName}, dishName: ${dishName}, dishPrice: ${dishPrice}`); //debug print
   const dish = {  
      name: dishName,
      price: dishPrice,
    };
    //Push the dish object to the corresponding _courses property's array
    this._courses[courseName].push(dish);
  },

Try adding the console.log() statement I’ve shown in this example to your code, and run it. You’ll still get the same error for now, but take note of the last line printed before the error occurs. Report back with your observations.

1 Like

Thank you for your help. I’ve added the Console.log() in and now I get this error:

courseName: appetizers, dishName: salad, dishPrice: 4
courseName: appetizers, dishName: bread, dishPrice: 2.5
courseName: appetizers, dishName: olives, dishPrice: 4.5
courseName: mains, dishName: Burger, dishPrice: 8
courseName: mains, dishName: steak, dishPrice: 10
courseName: mains, dishName: tofu, dishPrice: 5
courseName: dessert, dishName: ice cream, dishPrice: 3
/home/ccuser/workspace/learn-javascript-objects-meal-maker/app.js:38
       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:38:33)
    at Object.<anonymous> (/home/ccuser/workspace/learn-javascript-objects-meal-maker/app.js:62: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)

The arrow is pointing at the dot next to the push method. Does this mean that I am meant to added something else in that place or there is something wrong with that entire line?

1 Like

What it means is that you are calling the .push() method on something that is undefined (doesn’t exist). So, what could that be?
It’s saying that this._courses[courseName] is undefined.

If you look at the last line printed, what is the value of courseName?

Does the _courses object have a property with a key named whatever that is?

So what I am understanding from what you are telling me is that I have either left out courseName or that I have a spelling mistake within the code.

Right got it!

Thank you for your patience and explaining it to me. It is very much appreciated and needed.

Thank you so much so much :slight_smile:

1 Like

Reading potentially hundreds or thousands of lines of code to find a spelling error would be one way to find a bug, but it’s much easier to use the tools at our disposal. We have an error message which is quite specific, and we can log things to the console to make observations.

If you look at your menu object’s properties, and more specifically the _courses object’s properties we have:

The last value represented by courseName before the error was thrown was dessert.
Keep in mind that this in the line of code throwing the error refers to menu, so is this._courses['dessert'] defined? Does it exist?

Edit: Just noticed you had already spotted your issue. I had stepped away from my computer for a few minutes in the middle of my response, and didn’t see your last reply until after I posted it. Good work!

1 Like