Meal Maker Callstack error in Introduction to Javascript

hi heres the link of the exercise: https://www.codecademy.com/paths/web-development/tracks/web-dev-js-arrays-loops-objects/modules/learn-javascript-objects/projects/meal-maker

here’s the error im getting: /home/ccuser/workspace/learn-javascript-objects-meal-maker/app.js:26
return {
^

RangeError: Maximum call stack size exceeded
at Object.get _courses [as _courses] (/home/ccuser/workspace/learn-javascript-objects-meal-maker/app.js:26:6)
at Object.get appetizers [as appetizers] (/home/ccuser/workspace/learn-javascript-objects-meal-maker/app.js:8:16)
at Object.get _courses [as _courses] (/home/ccuser/workspace/learn-javascript-objects-meal-maker/app.js:27:24)
at Object.get appetizers [as appetizers] (/home/ccuser/workspace/learn-javascript-objects-meal-maker/app.js:8:16)
at Object.get _courses [as _courses] (/home/ccuser/workspace/learn-javascript-objects-meal-maker/app.js:27:24)
at Object.get appetizers [as appetizers] (/home/ccuser/workspace/learn-javascript-objects-meal-maker/app.js:8:16)
at Object.get _courses [as _courses] (/home/ccuser/workspace/learn-javascript-objects-meal-maker/app.js:27:24)
at Object.get appetizers [as appetizers] (/home/ccuser/workspace/learn-javascript-objects-meal-maker/app.js:8:16)
at Object.get _courses [as _courses] (/home/ccuser/workspace/learn-javascript-objects-meal-maker/app.js:27:24)
at Object.get appetizers [as appetizers] (/home/ccuser/workspace/learn-javascript-objects-meal-maker/app.js:8:16)

finaly here’s the code i have for the exercise:

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(appetizerIn){
this._course.appetizers = appetizerIn;
},
set mains(mainsIn){
this._course.mains = mainsIn;
},
set desserts(dessertsIn){
this._course.desserts = dessertsIn;
},
get _courses(){
return {
appetizers: this.appetizers,
mains: this.mains,
desserts: this.desserts,
};
},
addDishToCourse (courseName, dishName, dishPrice){
const dish = {
name: courseName,
price: dishPrice,
};
return this._courses[courseName].push(dish);
},
getRandomDishFromCourse (courseName){
const dishes = this._courses[courseName];
const randomIndex = Math.floor(Math.random()*dishes.lenght);
return dishes[randomIndex];
},
generateRandomMeal(){
const appetizers = this.getRandomDishFromCourse(‘appetizers’);
const mains = this.getRandomDishFromCourse(‘mains’);
const desserts = this.getRandomDishFromCourse(‘desserts’);
const totalPrice = appetizers.price + mains.price + desserts.price;
return Your meal is ${appetizers.name}, ${mains.name} and ${desserts.name} and the total price is ${totalPrice}
},
};

menu.addDishToCourse(‘appetizers’, ‘salad’, 4.00 );
menu.addDishToCourse(‘appetizers’, ‘wings’, 4.50 );
menu.addDishToCourse(‘appetizers’, ‘fries’, 5.00 );

menu.addDishToCourse(‘mains’, ‘steak’, 14.00 );
menu.addDishToCourse(‘mains’, ‘salmon’, 14.50 );
menu.addDishToCourse(‘mains’, ‘tofu’, 15.00 );

menu.addDishToCourse(‘desserts’, ‘ice cream’, 5.00 );
menu.addDishToCourse(‘desserts’, ‘coffee’, 2.50 );
menu.addDishToCourse(‘desserts’, ‘cake’, 4.00 );

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

please help, any help would be greatly appreciated!

The line I commented on above is the source of your Maximum call stack exceeded error. Just need to drop the _ from courses.
Then there is a spelling error here:

In your addDishToCourse method, you have another issue:

One last tip for future reference. When you post code, please format it as code. For me personally, I think it’s easiest to type 3 back tics on a line then paste your code starting on the next line, and type 3 more back tics on the line below your code like so:

```
code goes here
```

That will preserve your original spacing, indentations, etc. making your code much easier to read. Happy coding!

1 Like

With getters and setters there are a number of ways we can introduce a fly in the ointment. Circular references are the biggest one. I’ll leave you to search this in relation to JS to discover the technical writing on the subject.

When we plan to use setters and getters, The backing variable is always written on the property declaration.

_prop: %value%

The value can be any object. The support for this syntax is built in. Now it is up to us to leverage it in such a way as other authors can make sense of it. Not to worry. They know what a backing variable is.

The getter (and setter when deployed) always refer to the backing variable. However, we must understand three things,

  1. get and set are not methods (never invoked)
  2. set has some weird syntax when data structures are involved.
  3. The backing variable is not private.

On the third point, and it will take some inspection to uncover it, JS keeps it own ‘real’ property alive in the background. This will take more digging and reading for the technical details.

On the second, consider…

_prop:  []

or,

_prop: {}

How is a setter, which is given an assignment going to update these data structures?

set prop(value) {
    this._prop.push(value);
}

for arrays;

set prop(obj) {
    Object.assign(this._prop, obj);
}

for objects. In either case it’s not very obvious that this is the process taking place when we look at the assignment statement…

object.prop = value

or,

object.prop = {a: 42}

At this end of the transaction we have no indication that this is not a value assignment unless we are aware of the data structures. Some programmers object to this ambiguity. Myself, I have no comment. We just know that it works.

The first point, it is something we must come to respect as the nature of the beast. JS handles get and set in its own set way. We can be sure there are methods running in the background, but they are not our methods. To us, these are normal polls or assignments, and nothing more.

For privacy, never use backing variables anywhere in your program except getters and setters.

1 Like

Thank you so much it finally worked!

1 Like

Hi midlidner,

I got the same issue as the member above. I even dropped the ‘_’, but the same error represents.

What may be wrong?

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: courseName,
        price: dishPrice
     };
    return this._courses[courseName].push(dish)
  },
  getRandomDishFromCourse(courseName){
    dishes = this._courses[courseName]
    let 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 total_price = appetizer.price + main.price + dessert.price
    return `the total price of your meal is ${total_price}`
  }
}
 
menu.addDishToCourse('appetizers', 'polpette', 5)
menu.addDishToCourse('appetizers', 'arancino', 3)
menu.addDishToCourse('appetizers', 'ravioli',8)

menu.addDishToCourse('mains', 'pasta',8)
menu.addDishToCourse('mains', 'lasagne', 10)
menu.addDishToCourse('mains', 'ravioli', 9)

menu.addDishToCourse('desserts', 'ice cream', 6)
menu.addDishToCourse('desserts', 'cheesecake', 6)
menu.addDishToCourse('desserts', 'ravioli', 6)


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



Having removed the _ from courses here:

you made all references to this._courses... undefined. The problem is here:

get _courses() should be get courses() to avoid the circular reference.

1 Like