Meal Maker Exercise - I've got it working, but I don't understand why it works

I have this all working after following along with the video, but I’m not totally clear on WHY it works. My two questions are:

  1. the “dish” object that is created on line 33: Why am I able to access it from other places? I thought this was part of a code block and therefore not globally accessible?

  2. The setters on lines 16 - 24. I had thought that using a syntax like this.array = 1 would completely overwrite the array and that I should be using a .push or .append or something similar. But when the code is run at the end and I reuse the setter multiple times it seems to simply add to the array. Have I misunderstood the behaviour of the ‘=’ in this context?

Thanks!

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 courseFoods = this._courses[courseName];
    let courseIndex = Math.random()*courseFoods.length;
    courseIndex = Math.floor(courseIndex);
    // console.log(dishes.length);
    // console.log(dishes);
    // console.log(index);
    return courseFoods[courseIndex];
  },
  generateRandomMeal() {
    const appetizer = menu.getRandomDishFromCourse('appetizers');
    const main = menu.getRandomDishFromCourse('mains');
    const dessert = menu.getRandomDishFromCourse('desserts');
    const totalPrice = appetizer.price + main.price + dessert.price;
    console.log(appetizer.price)
    return `Your meal is ${appetizer.name}, then ${main.name}, then ${dessert.name}. It will cost \$${totalPrice}`
    
  }
};
// menu.addDishToCourse('mains', 'water', 5)
// console.log(menu.courses);
menu.addDishToCourse('appetizers', 'salad', 4.50);
menu.addDishToCourse('appetizers', 'wings', 5.00);
menu.addDishToCourse('appetizers', 'fries', 7.50);
menu.addDishToCourse('mains', 'burger', 12.15);
menu.addDishToCourse('mains', 'tofu', 13.32);
menu.addDishToCourse('mains', 'curry', 15.20);
menu.addDishToCourse('desserts', 'ice cream', 7.60);
menu.addDishToCourse('desserts', 'cookies', 6.80);
menu.addDishToCourse('desserts', 'tea', 3.75);

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


1 Like

Hey there!

You’re correct that the dish constant exists only within the scope of your addDishToCourse() function. However, can you see what you’re also doing within that function that might make it possible to use the created object elsewhere in your code? (I’m trying to push you towards the answer here…)

I think you understand the behaviour of the assignment operator just fine, but I think you don’t quite understand how your program is working in relation to the setters you have defined.

I have modified your program slightly, as below:

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) {
    console.log("set appetizers called"); // added console.log call
    this._courses.appetizers = appetizers;
  },
  set mains(mains) {
    console.log("set mains called"); // added console.log call
    this._courses.mains = mains;
  },
  set desserts(desserts) {
    console.log("set desserts called"); // added console.log call
    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 courseFoods = this._courses[courseName];
    let courseIndex = Math.random()*courseFoods.length;
    courseIndex = Math.floor(courseIndex);
    // console.log(dishes.length);
    // console.log(dishes);
    // console.log(index);
    return courseFoods[courseIndex];
  },
  generateRandomMeal() {
    const appetizer = menu.getRandomDishFromCourse('appetizers');
    const main = menu.getRandomDishFromCourse('mains');
    const dessert = menu.getRandomDishFromCourse('desserts');
    const totalPrice = appetizer.price + main.price + dessert.price;
    console.log(appetizer.price)
    return `Your meal is ${appetizer.name}, then ${main.name}, then ${dessert.name}. It will cost \$${totalPrice}`
    
  }
};
// menu.addDishToCourse('mains', 'water', 5)
// console.log(menu.courses);

menu.addDishToCourse('appetizers', 'salad', 4.50);
menu.addDishToCourse('appetizers', 'wings', 5.00);
menu.addDishToCourse('appetizers', 'fries', 7.50);
menu.addDishToCourse('mains', 'burger', 12.15);
menu.addDishToCourse('mains', 'tofu', 13.32);
menu.addDishToCourse('mains', 'curry', 15.20);
menu.addDishToCourse('desserts', 'ice cream', 7.60);
menu.addDishToCourse('desserts', 'cookies', 6.80);
menu.addDishToCourse('desserts', 'tea', 3.75);

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

// lets test it, then, because until now you haven't called any setters!
new_dish = {name: 'tarka dhal', price: 1000.0};
menu.mains = [new_dish];
console.log(menu.mains);

You’ll notice that, on lines 17/21/25 I have added new calls to console.log within the setter for each course.

Additionally, I have added new code from line 77 onwards - after your console.log(meal); call.

This new code creates a new dish, “tarka dhal”, with a cost of 1000, and assigns it to menu.mains. We then output the new mains to the console, and for the entire program the output is thus:

4.5
Your meal is salad, then burger, then cookies. It will cost $23.45
set mains called
[ { name: 'tarka dhal', price: 1000 } ]
  • 4.5 is the output from line 56 (console.log(appetizer.price)),
  • Your meal is salad.... is the output from line 75 (console.log(meal)),
  • set mains called is my debugging line being shown because we’ve called the mains setter,
  • and [ { name: 'tarka dhal', price: 1000 } ] is the output of line 80 (console.log(menu.mains)).

As you can see, your code makes no calls to the setters. Mine does, because I make a direct assignment to the mains property. (I think “property” is the correct terminology… JS isn’t my primary coding language!).

Hopefully that helps you understand why your program works the way it does, and answers your questions. :slight_smile:

If anything is still unclear, though, please say so and we’ll try and help you out. :slight_smile:

Bonus points also if you know why I chose tarka dhal...

You haven’t heard of this particular lord of the mighty Vindaloovian Empire?!

Responding somewhat to keep this thread alive. I’ve noticed these lock after 18 hours and I only get the chance to work on these in the evenings. Thanks for your responses… I now realize that The push call in the dish object is doing all this work. Urg. Thanks for PUSHing me to be more observant.

The rest of it I’ll have to take a look at a bit later.

1 Like

@alexcraig can we please not have threads lock on solve, it’s like slamming handcuffs down on a thread, and the 18 amount doesn’t seem well thought out either… more reasonable is something like 30 days by default on thread creation, not on solve

4 Likes

Ohhhh, I understand what’s happening… It’s not overwriting, because I’m writing it directly into the dish object, rather than using the setters. Very odd (and a bit confusing) that the requirements of the steps in the exercise tell us to put in setters when they aren’t actually used. Or maybe Codecademy WANTS me to to go to the forums and learn a lesson I won’t forget… sneaky.

I had to go hinting for the Red Dwarf reference. Well puned… now I’m hungry for a nice lamb dhal. Or maybe I just want to re-read Matilda or The Witches. Or is that the wrong Dahl?

Thanks!

1 Like

I have virtually the exact same code, but keep getting a “TypeError: Cannot read property ‘push’ of undefined”

Does anyone have any ideas?

full code below:

const menu = {
  _courses: {
    appetizers: [],
    mains: [],
    desserts: [],
  },
    get courses () {
    return Object.entries(this._courses)
    },
  get appetizers () {
    return this._courses.appetizers
  },
  get mains () {
    return this._courses.mains
  },
  get desserts () {
    return this._courses.desserts
  },
  set appetizers (appetizersIn) {
      this._courses.appetizers = appetizersIn
  },
  set mains (mainsIn) {
      this._courses.mains = mainsIn
  },
  set desserts (dessertsIn) {
      this._courses.desserts = dessertsIn
  },
  addDishToCourse(courseName, dishName, dishPrice) {
    const dish = {
      name: dishName,
      price: dishPrice,
    };
    return this._courses[courseName].push(dish);
  },
  getRandomDishFromCourse (courseName) {
    const dishes = this.courses
    const index = Math.floor(Math.random() * dishes.length)
    return dishes[index]
  },
  generateRandomMeal() {
    const appetizer = this.getRandomDishFromCourse('appetizers')
    const main = this.getRandomDishFromCourse('main')
    const dessert = this.getRandomDishFromCourse('dessert')
    const mealPrice = appetizer[1][1] + main[1][1] + dessert[1][1];
    let mealString = `${appetizer[1][0]}, ${main[1][0]}, and ${dessert[1][0]}, ${mealPrice} dollars.`;
return mealString
  }
  };

// menu.appetizers = ['spring rolls', 12];
// menu.mains = ['pasta', 17];
// menu.desserts = ['brownies, bro', 11];
menu.addDishToCourse('appetizers', 'popcorn chicken', 15);
menu.addDishToCourse('main', 'asparagus n stuff', 21);
menu.addDishToCourse('dessert', 'ice cream', 14);

console.log(menu.courses)

// console.log(menu.generateRandomMeal())

Welcome to the forums!

You have made exactly the same error as @jgrinks, only with a different course…

Thanks for the welcome!

I didn’t see that @jgrinks made any error, it seemed that he was confused about why/how something was working, not why it wasn’t working. Perhaps I’m not understanding something from earlier in the thread?

1 Like

Gah, sorry… I feel like all I’ve been answering on here the past few days has been meal maker questions, and they’re merging together in my brain! :frowning:

You’ve made the same error as the OP did in this thread, just in a different course:

That should point you in the right direction. :slight_smile:

No worries - I feel similarly about manufacturing threads on reddit.

Thanks for the direction!

1 Like

No worries. :slight_smile:

If you get stuck with anything else, start a topic and we’ll try and help. :slight_smile:

1 Like