Valeria Melinte
Valeria Melinte

Reputation: 137

Dynamically assign properties and values to a javascript object

I am trying to create a week meal planner. At the moment the scenario is the following:

  1. You click on a time of day (breakfast/lunch/dinner) + day of the week;
  2. A list of recipes fades in;
  3. By selecting (clicking) on a recipe you assign this recipe to the day of th week + time of day previously selected.

I want to store all this data into a JS object, ideally I would like to dynamically create the day object with breakfast/lunch/dinner as keys and recipe as the value but I'm a little stuck here. I've created a jsfiddle as a little demo of what I'm trying achieve. The problem is that when I select for e.g. recipe-1 for Monday breakfast it does correctly get stored but then, if I select recipe-2 for lunch - breakfast gets reassinged a value of 0. Can someone help me understand why is this happening and guide me to a better approach? Any suggestion/ help is very much appreciated! Thank you very much!

// find elements
var data_day = '',
time_of_day = '',
recipe = $('.recipes .recipe'),
weekly_recipes = {
  'week_day': {}
};

// show list of recipes
$("[data-time]").on("click", function(){
	$('.recipes').fadeIn();
  time_of_day = $(this).attr('data-time');
  data_day = $(this).parents('.column').attr('data-day');
});

recipe.on('click', function(){
	var recipe_name = $(this).attr('data-recipe');
  weekly_recipes.week_day[data_day] = {
  	'breakfast': 0,
    'lunch': 0,
    'dinner': 0
	};
  $('.recipes').fadeOut();
	weekly_recipes.week_day[data_day][time_of_day] = recipe_name;
	$('.meal-plan').text(JSON.stringify(weekly_recipes));
	console.log(weekly_recipes);
});
body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

.column{
  width: 25%;
  float: left;
  padding: 10px;
}
.column strong{
  display: block;
  margin-bottom: 20px;
}
.column .wrp{
  background: white;
}
.column [data-time]{
  cursor: pointer;
  margin-bottom: 10px;
}
.recipes{
  width: 100%;
  display: none;
  clear: both;
  margin-top: 40px;
  background: white;
}
.recipes span{
  display: block;
  cursor: pointer;
  margin-top: 10px;
}
.meal-plan{
  margin-top: 20px;
  background: white;
  clear: both;
  margin-top: 40px;
  background: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="column" data-day="monday">
  <div class="wrp">
    <strong>Monday</strong>
  <div data-time="breakfast">Breakfast</div>
  <div data-time="lunch">Lunch</div>
  <div data-time="dinner">Dinner</div>
  </div>
</div>
<div class="column" data-day="tuesday">
  <div class="wrp">
    <strong>Tuesday</strong>
  <div data-time="breakfast">Breakfast</div>
  <div data-time="lunch">Lunch</div>
  <div data-time="dinner">Dinner</div>
  </div>
</div>

<div class="column" data-day="wednesday">
  <div class="wrp">
    <strong>Wednesday</strong>
  <div data-time="breakfast">Breakfast</div>
  <div data-time="lunch">Lunch</div>
  <div data-time="dinner">Dinner</div>
  </div>
</div>

<div class="recipes">
  <div class="recipe" data-recipe="recipe-1">
   <span data-recipe="recipe-1">recipe 1</span>
  </div>
  <div class="recipe" data-recipe="recipe-2">
   <span data-recipe="recipe-2">recipe 2</span>
  </div>
</div>

<div class="meal-plan">
</div>
</div>

Upvotes: 2

Views: 113

Answers (2)

Calvin Nunes
Calvin Nunes

Reputation: 6516

Your code is very near to work, you only need to take care when the object of some day already exists to not create it again.

See below code, you just create a new day when it doesn't exist, if it already exists, then just add the recipe to the time_of_day of that day

var data_day = '',
time_of_day = '',
recipe = $('.recipes .recipe'),
weekly_recipes = {
  'week_day': {}
};

$("[data-time]").on("click", function(){
	$('.recipes').fadeIn();
  time_of_day = $(this).attr('data-time');
  data_day = $(this).parents('.column').attr('data-day');
});

recipe.on('click', function(){
  var recipe_name = $(this).attr('data-recipe');
  
  //CHECK FOR DAY EXISTANCE
  if (weekly_recipes.week_day[data_day] == null || !weekly_recipes.week_day.hasOwnProperty(data_day)){
    weekly_recipes.week_day[data_day] = {
      'breakfast': 0,
      'lunch': 0,
      'dinner': 0
    };
  }
  
  weekly_recipes.week_day[data_day][time_of_day] = recipe_name;
  $('.recipes').fadeOut();
	$('.meal-plan').text(JSON.stringify(weekly_recipes));
  console.clear()
	console.log(weekly_recipes);
});
body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

.column{
  width: 25%;
  float: left;
  padding: 10px;
}
.column strong{
  display: block;
  margin-bottom: 20px;
}
.column .wrp{
  background: white;
}
.column [data-time]{
  cursor: pointer;
  margin-bottom: 10px;
}
.recipes{
  width: 100%;
  display: none;
  clear: both;
  margin-top: 40px;
  background: white;
}
.recipes span{
  display: block;
  cursor: pointer;
  margin-top: 10px;
}
.meal-plan{
  margin-top: 20px;
  background: white;
  clear: both;
  margin-top: 40px;
  background: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="column" data-day="monday">
  <div class="wrp">
    <strong>Monday</strong>
  <div data-time="breakfast">Breakfast</div>
  <div data-time="lunch">Lunch</div>
  <div data-time="dinner">Dinner</div>
  </div>
</div>
<div class="column" data-day="tuesday">
  <div class="wrp">
    <strong>Tuesday</strong>
  <div data-time="breakfast">Breakfast</div>
  <div data-time="lunch">Lunch</div>
  <div data-time="dinner">Dinner</div>
  </div>
</div>

<div class="column" data-day="wednesday">
  <div class="wrp">
    <strong>Wednesday</strong>
  <div data-time="breakfast">Breakfast</div>
  <div data-time="lunch">Lunch</div>
  <div data-time="dinner">Dinner</div>
  </div>
</div>

<div class="recipes">
  <div class="recipe" data-recipe="recipe-1">
   <span data-recipe="recipe-1">recipe 1</span>
  </div>
  <div class="recipe" data-recipe="recipe-2">
   <span data-recipe="recipe-2">recipe 2</span>
  </div>
</div>
<div class="meal-plan"></div>

Upvotes: 2

void
void

Reputation: 36703

You were almost there but the whole issue was that you were resetting the object to default 0 value everytime the user clicks on the recepie.

Instead you need to put some check that if it is already initialized then dont reset it to default.

I have added the below code:

 if(!weekly_recipes.week_day.hasOwnProperty(data_day) || Object.keys(weekly_recipes.week_day[data_day]).length === 0){
    weekly_recipes.week_day[data_day] = {
      'breakfast': 0,
      'lunch': 0,
      'dinner': 0
    };
  }

See the working code below:

// find elements
var data_day = '',
  time_of_day = '',
  recipe = $('.recipes .recipe'),
  weekly_recipes = {
    'week_day': {}
  };

// show list of recipes
$("[data-time]").on("click", function() {
  $('.recipes').fadeIn();
  time_of_day = $(this).attr('data-time');
  data_day = $(this).parents('.column').attr('data-day');
});

recipe.on('click', function() {
  var recipe_name = $(this).attr('data-recipe');
  console.log(weekly_recipes.week_day[data_day]);
  if (!weekly_recipes.week_day.hasOwnProperty(data_day) || Object.keys(weekly_recipes.week_day[data_day]).length === 0) {
    weekly_recipes.week_day[data_day] = {
      'breakfast': 0,
      'lunch': 0,
      'dinner': 0
    };
  }
  $('.recipes').fadeOut();
  weekly_recipes.week_day[data_day][time_of_day] = recipe_name;
  $('.meal-plan').text(JSON.stringify(weekly_recipes));
  console.log(weekly_recipes);
});
body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

.column {
  width: 25%;
  float: left;
  padding: 10px;
}

.column strong {
  display: block;
  margin-bottom: 20px;
}

.column .wrp {
  background: white;
}

.column [data-time] {
  cursor: pointer;
  margin-bottom: 10px;
}

.recipes {
  width: 100%;
  display: none;
  clear: both;
  margin-top: 40px;
  background: white;
}

.recipes span {
  display: block;
  cursor: pointer;
  margin-top: 10px;
}

.meal-plan {
  margin-top: 20px;
  background: white;
  clear: both;
  margin-top: 40px;
  background: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="column" data-day="monday">
  <div class="wrp">
    <strong>Monday</strong>
    <div data-time="breakfast">Breakfast</div>
    <div data-time="lunch">Lunch</div>
    <div data-time="dinner">Dinner</div>
  </div>
</div>
<div class="column" data-day="tuesday">
  <div class="wrp">
    <strong>Tuesday</strong>
    <div data-time="breakfast">Breakfast</div>
    <div data-time="lunch">Lunch</div>
    <div data-time="dinner">Dinner</div>
  </div>
</div>

<div class="column" data-day="wednesday">
  <div class="wrp">
    <strong>Wednesday</strong>
    <div data-time="breakfast">Breakfast</div>
    <div data-time="lunch">Lunch</div>
    <div data-time="dinner">Dinner</div>
  </div>
</div>

<div class="recipes">
  <div class="recipe" data-recipe="recipe-1">
    <span data-recipe="recipe-1">recipe 1</span>
  </div>
  <div class="recipe" data-recipe="recipe-2">
    <span data-recipe="recipe-2">recipe 2</span>
  </div>
</div>

<div class="meal-plan">
</div>
</div>

Upvotes: 3

Related Questions