Meal maker


#1

https://www.codecademy.com/courses/learn-javascript-objects/projects/meal-maker?course_redirect=introduction-to-javascript
I have had a good stab at this - over a few days and have also had some chat help - but I still can’t crack the random meal generator exercise.
Here is my code so far. It seems to be a problem with the random dish generator , as my dishes seem to be added to my courses ok. Any help will be greatly appreciated!

let menu = {
// creating 3 course properties
_courses: {
_appetizers: [],
_mains: [],
_desserts: []
},

// a setter method for each course property which returns an object with properties for each course
set appetizers(newAppetizer) {
this._appetizers = newAppetizer;
},
set mains(newMain) {
this._mains = newMain;
},
set desserts(newDessert) {
this._desserts = newDessert;
},

// a getter method for each course
get courses() {
return {
appetizers: this._courses._appetizers,
mains: this._courses._mains,
desserts: this._courses._desserts
}
},

// a method which will be used to add a new dish to the specified course
addDishToCourse(courseName, dishName, dishPrice){
let dish = {
_name: dishName,
_price: dishPrice
};
courseName.push(dish);
},

// a function to get a random dish from the menu to generate a random meal
getRandomDishFromCourse(courseName){
const dishes = this._courses[courseName];
const randomIndex = Math.floor(Math.random() * dishes.length);
return randomIndex
},

// a function to automatically generate a random meal
generateRandomMeal() {
let appetizer = this.getRandomDishFromCourse(this.courses.appetizers);
let main = this.getRandomDishFromCourse(this.courses.mains);
let dessert = this.getRandomDishFromCourse(this.courses.desserts);
let totalPrice = appetizer.price + main.price + dessert.price;
return Your meal is ${appetizer.name}, ${main.name} and ${dessert.name}. The total price is ${totalPrice}.;
}
};
menu.addDishToCourse(menu.courses.appetizers, ‘Salad’, 4.25)
menu.addDishToCourse(menu.courses.appetizers, ‘prawns’, 6.25)
menu.addDishToCourse(menu.courses.appetizers, ‘soup’, 3.50)

menu.addDishToCourse(menu.courses.mains, ‘Big Salad’, 8.25)
menu.addDishToCourse(menu.courses.mains, ‘king prawns’, 9.25)
menu.addDishToCourse(menu.courses.mains, ‘risotto’, 8.50)

menu.addDishToCourse(menu.courses.desserts, ‘fruit Salad’, 3.25)
menu.addDishToCourse(menu.courses.desserts, ‘tiramisu’, 4.25)
menu.addDishToCourse(menu.courses.desserts, ‘rice pudding’, 4.50)

let meal = menu.generateRandomMeal();


#2

Hi @mmecholet,

In your getRandomDishFromCourse method, what type of object are you returning here? …

return randomIndex

Consider whether you instead need to use randomIndex to access and return a different object.


#3

So maybe it should be
dishes[randomIndex] ?
The random thing always confuses me.
I have tried dishes[randomIndex] but it still has a problem:

TypeError: Cannot read property ‘length’ of undefined
at Object.getRandomDishFromCourse (/home/ccuser/workspace/learn-javascript-objects-meal-maker/app.js:41:58)
at Object.generateRandomMeal (/home/ccuser/workspace/learn-javascript-objects-meal-maker/app.js:47:22)

Is it still the randomIndex which is the problem?


#4

This getRandomDishFromCourse method conforms to the instructions in step 10 of the project …

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

Are your getters and setters in the correct scope? The final closing bracket here excludes the getter and setter methods that follow from _courses

let menu = {
// creating 3 course properties
_courses: {
_appetizers: [],
_mains: [],
_desserts: []
},

Of course, if you remove that closing bracket, you will need to make other adjustments to the code to accommodate that change.


#5

Thank you - I see that I had the bracket in the wrong place. I’ve now corrected that - but I still have a few problems.
Here is my code now:

let menu = {
// creating 3 course properties
_courses: {
_appetizers: [],
_mains: [],
_desserts: [],

// a setter method for each course property which returns an object with properties for each course
set appetizers(newAppetizer) {
this._appetizers = newAppetizer;
},
set mains(newMain) {
this._mains = newMain;
},
set desserts(newDessert) {
this._desserts = newDessert;
},

// a getter method for each course
get courses() {
return {
appetizers: this._courses._appetizers,
mains: this._courses._mains,
desserts: this._courses._desserts
}
}
},//end of course object

// a method which will be used to add a new dish to the specified course
addDishToCourse(courseName, dishName, dishPrice){
let dish = {
_name: dishName,
_price: dishPrice
};
courseName.push(dish);
},

// a function to get a random dish from the menu to generate a random meal
getRandomDishFromCourse(courseName){
const dishes = this._courses[courseName];
const randomIndex = Math.floor(Math.random() * dishes.length);
return dishes[randomIndex];
},

// a function to automatically generate a random meal
generateRandomMeal() {
let appetizer = this.getRandomDishFromCourse(this.courses.appetizers);
let main = this.getRandomDishFromCourse(this.courses.mains);
let dessert = this.getRandomDishFromCourse(this.courses.desserts);
let totalPrice = appetizer.price + main.price + dessert.price;
return Your meal is ${appetizer.name}, ${main.name} and ${dessert.name}. The total price is ${totalPrice}.;
}
}// end of menu object

menu.addDishToCourse(menu.courses.appetizers, ‘Salad’, 4.25);
menu.addDishToCourse(menu.courses.appetizers, ‘prawns’, 6.25);
menu.addDishToCourse(menu.courses.appetizers, ‘soup’, 3.50);

menu.addDishToCourse(menu.courses.mains, ‘Big Salad’, 8.25);
menu.addDishToCourse(menu.courses.mains, ‘king prawns’, 9.25);
menu.addDishToCourse(menu.courses.mains, ‘risotto’, 8.50);

menu.addDishToCourse(menu.courses.desserts, ‘fruit Salad’, 3.25);
menu.addDishToCourse(menu.courses.desserts, ‘tiramisu’, 4.25);
menu.addDishToCourse(menu.courses.desserts, ‘rice pudding’, 4.50);

console.log( menu.appetizers)

let meal = menu.generateRandomMeal();

The error now is:
home/ccuser/workspace/learn-javascript-objects-meal-maker/app.js:56
menu.addDishToCourse(menu.courses.appetizers, ‘Salad’, 4.25);
^

TypeError: Cannot read property ‘appetizers’ of undefined
at Object. (/home/ccuser/workspace/learn-javascript-objects-meal-maker/app.js:56:34)
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)
at bootstrap_node.js:542:3

Please can I have some more help? I’ve been boggling at this now for so long !


#6

You still need some getters. An example would be …

    get appetizers() {
      return this._appetizers;
    },

#7

Yes! You’re right!
I’ve now got it working - it took me sooo long!
Still - I must have learnt something from this…
Many thanks.


#8

Actually - I spoke too soon!
I printed out what I thought was a success to look over and enjoy - but when I did I saw that my getters and setters were empty?!
Here is the code that worked:

let menu = {
//create a courses property object
_courses: {
//creating the 3 course properties
appetizers: [],
mains: [],
desserts: []
},//end of the courses object
// a setter method for each course
set appetizers(newAppetizer) {},
set mains(newMain){},
set desserts(newDessert){},
// a getter method for each course
get appetizers(){},
get mains(){},
get desserts(){},
// a getter method for the courses property
get courses(){
return {
appetizers: this._courses.appetizers,//this uses the appetizer getter methods
mains: this._courses.mains,
desserts: this._courses.desserts,
};
},

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

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

generateRandomMeal: function(){
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}. The total price ${totalPrice}.;
}
}; //end of menu object

menu.addDishToCourse(‘appetizers’, ‘Salad’, 4.25);
menu.addDishToCourse(‘appetizers’, ‘prawns’, 6.25);
menu.addDishToCourse(‘appetizers’, ‘soup’, 3.50);

menu.addDishToCourse(‘mains’, ‘Big Salad’, 8.25);
menu.addDishToCourse(‘mains’, ‘king prawns’, 9.25);
menu.addDishToCourse(‘mains’, ‘risotto’, 8.50);

menu.addDishToCourse(‘desserts’, ‘fruit Salad’, 3.25);
menu.addDishToCourse(‘desserts’, ‘tiramisu’, 4.25);
menu.addDishToCourse(‘desserts’, ‘rice pudding’, 4.50);

console.log( menu.courses.appetizers);

let meal = menu.generateRandomMeal();

When I filled in the getters and setters - yet again it didn’t work.
I’m tearing my hair out!

Here is the updated code which doesn’t work.
Any help greatly appreciated.

let menu = {
//create a courses property object
_courses: {
//creating the 3 course properties
appetizers: [],
mains: [],
desserts: []
},//end of the courses object
// a setter method for each course
set appetizers(newAppetizer) {
this.appetizers = newAppetizer;
},
set mains(newMain){
this.mains = newMain;
},
set desserts(newDessert){
this.desserts = newDessert;
},
// a getter method for each course
get appetizers(){
return this.appetizers;
},
get mains(){
return this.mains;
},
get desserts(){
return this.desserts;
},
// a getter method for the courses property
get courses(){
return {
appetizers: this._courses.appetizers,//this uses the appetizer getter methods
mains: this._courses.mains,
desserts: this._courses.desserts,
};
},

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

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

generateRandomMeal: function(){
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}. The total price ${totalPrice}.;
}
}; //end of menu object

menu.addDishToCourse(‘appetizers’, ‘Salad’, 4.25);
menu.addDishToCourse(‘appetizers’, ‘prawns’, 6.25);
menu.addDishToCourse(‘appetizers’, ‘soup’, 3.50);

menu.addDishToCourse(‘mains’, ‘Big Salad’, 8.25);
menu.addDishToCourse(‘mains’, ‘king prawns’, 9.25);
menu.addDishToCourse(‘mains’, ‘risotto’, 8.50);

menu.addDishToCourse(‘desserts’, ‘fruit Salad’, 3.25);
menu.addDishToCourse(‘desserts’, ‘tiramisu’, 4.25);
menu.addDishToCourse(‘desserts’, ‘rice pudding’, 4.50);

console.log( menu.courses.appetizers);

let meal = menu.generateRandomMeal();

So I realise this had disappeared, but adding it back in still doesn’t get me a random meal generated

return dishes[randomIndex];


#9

Panic over!!
Many thanks again . Phew.
I must print this out immediately and learn it by heart!


#10

Try out this revision of a portion of your code …

let menu = {
  // creating 3 course properties
  _courses: {
    _appetizers: [],
    _mains: [],
    _desserts: [],
 
// a setter and getter method for each course property which returns an object with properties for each course
  set appetizers(newAppetizer) {
    this._appetizers = newAppetizer;
  },
    get appetizers() {
      return this._appetizers;
    },
  set mains(newMain) {
    this._mains = newMain;
},
    get mains() {
      return this._mains;
    },
  set desserts(newDessert) {
    this._desserts = newDessert;
  },
  get desserts() {
      return this._desserts;
    },
  // a getter method for each course
  get courses() {
    return {
      appetizers: this._courses._appetizers,
      mains: this._courses._mains,
      desserts: this._courses._desserts
    }
  }
  }, //end of course object
  
// a method which will be used to add a new dish to the specified course
  addDishToCourse(courseName, dishName, dishPrice){
    let dish = {
      name: dishName,
      price: dishPrice
    };
    this._courses[courseName].push(dish);
  },
  
  // a function to get a random dish from the menu to generate a random meal
  getRandomDishFromCourse(courseName){
    const dishes = this._courses[courseName];
    const randomIndex = Math.floor(Math.random() * dishes.length);
    return dishes[randomIndex];
  },
  
// a function to automatically generate a random meal
generateRandomMeal() {
  let appetizer = this.getRandomDishFromCourse('appetizers');
  let main = this.getRandomDishFromCourse('mains');
  let dessert = this.getRandomDishFromCourse('desserts');
  let totalPrice = appetizer.price + main.price + dessert.price;
    return `Your meal is ${appetizer.name}, ${main.name} and ${dessert.name}. The total price is ${totalPrice}.`;
  }
} // end of menu object

You will need to add to it the statements such as …

menu.addDishToCourse('mains', 'Baked Flounder', 11.50);

#11

In my code which seems to work the curly end bracket for the course object is after the empty arrays created for the appetizers, mains and desserts. When I move it to after the getters and setters as in the code above the code doesn’t work any more.
Which is the correct place for that end bracket?


#12

My own solution begins as follows …

let menu = {
  _courses: {
    _appetizers: [],
    _mains: [],
    _desserts: [],
    _takeouts: [],
    
    get appetizers() {
      return this._appetizers;
    },
    set appetizers(appetizersIn) {
      this._appetizers = appetizersIn;
    },

Note that there is no closing bracket separating the getters and setters from the preceding empty arrays. Therefore, the getters and setters are part of the _courses object.

Also note that my solution departs from the project specifications by adding a _takeouts array. This was done as a personal challenge, and required additional revisions of some of the methods.


#13

Gosh - sounds complex. I’m very much a beginner on this - so sticking to the project specifications very closely. It’s interesting to see there can be variants though. Would you be able to explain how the getters and setters can either be part of the _courses object or outside of it?


#14

The code in this post is a revised version of the code that you provided early in this discussion, but with the statements that populate menu removed.

Note that in the revised code, there is no closing curly bracket separating the empty arrays from the getters and setters. Therefore, they are all part of the _courses object. This is as they should be, because the purpose of those getters and setters is to work with those arrays.

If you separate the getters and setters from the _courses object with a closing curly bracket, they will not be useful, because they will be in a separate scope from the arrays with which they are designed to work.

(Edited on May 1, 2018 for clarification)


#15

Just in case you checked the hint …

The following screen capture was made on May 2, 2018 …

07%20AM

Well, the hint is incorrect. The first closing curly bracket separates the getters and setters from the properties with which they are intended to work.

Getters and setters are discussed in Learn JavaScript: Objects: Getters and Setters I and in some of the exercises that follow. Here is a screen capture from there …

06%20AM

Note that this line …

  _seatingCapacity: 120,

… and this one …

  set seatingCapacity(newCapacity) {

… are in the same scope. That is as it should be.


#16

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.