Meal Maker project error/ undefined.push

Hi guys I keep getting this error ( /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)

I watched the video that was made a few years ago and my syntax is pretty much identical to that…
here is the code:
https://gist.github.com/019ebbfbe3c95ca98e699270eb12f9e7

any help would be great but an explanation as to where i went wrong and why it is wrong would be even more appreciated.

so .push() is an array specific method, calling .push() on undefined gives an error:

undefined.push(1)

So then the next question you should ask yourself is: how/why do I get undefined? When you use a property which does not exists on an object:

console.log({}.nonExisting); // logs: undefined

so then to debug this problem, we would need to log the available properties and the properties which you use:

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

I use Object.keys() to get all the available keys/properties, but you could also just log the course object.

Okay thats great and all but I still dont understand because its not undefined, [courseName] would refer to either of these strings ‘appetizers’, ‘mains’, ‘desserts’. So, when I call .push on it, that parameter has already been defined as one of three pramaters once generateRandomMeal(courseName, dishName, dishPrice) is called on the whole function.

Turns out the issue was a typo when calling addDishToCourse() I missed out the s’s on the end of desserts, that makes sense on the debugging now because it will find the miss spelling on desserts

But there is no check if the arguments/values you provide for the courseName parameter of addDishToCourse method is actually one of the three keys/properties of the courses object

Seems you have it resolved.

I partially blame JavaScript here as well, javascript should throw an error when a key/property does not exists on an object. That would make it a lot easier to debug this kind of issue

I suppose, in time we learn to navigate the rough edges of any programming languages.

2 Likes

Thanks For the help though you definitly pushed me in the right direction

1 Like

Hi. I’m stuck at the same point . But i have combed back and forth my code and STILL getting undefined, when trying to push the dish object. I have checked the keys and they exist. but _courses{coursesName) still is undefined.

const menu = {
  _courses: {
    appetizers: [],
    mains: [],
    desserts: []
  },
  get appetizers() {
    return this._courses.appetizers;

  },
  set appetizers(appetizers) {
    this._courses.appetizers = appetizers

  },
  get mains() {
    return this._courses.mains;
  },
  set mains(mains) {
    this._courses.mains = mains
  },
  get desserts() {
    return this._courses.desserts;
  },
  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
  };
  console.log(Object.keys(this._courses,courseName))
  return this._courses[courseName].push(dish);
  },
1 Like

where is the rest of your code?

1 Like

Oh, sorry. Here it is.

const menu = {
  _courses: {
    appetizers: [],
    mains: [],
    desserts: []
  },
  get appetizers() {
    return this._courses.appetizers;

  },
  set appetizers(appetizers) {
    this._courses.appetizers = appetizers

  },
  get mains() {
    return this._courses.mains;
  },
  set mains(mains) {
    this._courses.mains = mains
  },
  get desserts() {
    return this._courses.desserts;
  },
  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
  };
  console.log(Object.keys(this._courses,courseName))
  return this._courses["courseName"].push(dish)
  },

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

  generateRandomMeal() {
    let appetizer = getRandomDishFromCourse("appetizers");
    let mains = getRandomDishFromCourse("mains");
    let desserts = getRandomDishFromCourse("desserts");
  }
}

menu.addDishToCourse("main","wings", 4.50)
```

exactly the same problem? except you have 'main' instead of 'mains', but you should be able to debug that with the same steps I provided for OP?

1 Like

You are right.

I thought that courseName parameter was a variable that was going to be added to the menu object. But it actually points to the object keys .

Thank you !!