Reputation: 53
On the function "createIngrList", it should take all the ingredient names, such as "Butter", "Beef", "Onion", etc., and turn it into buttons. So each button should have a text with the name of an ingredient written on it. As of now, there is just 4 buttons with "undefined" written on it. If possible, all the repeating ingredients such as "Onion" should not be made into button twice. Once is enough.
mealObj = {
Steak: {
ingr1: {
Name: "Butter",
ingrType: "other",
amount: "2",
amountType: "tbsp",
cal: "10",
},
ingr2: {
name: "Parsley",
ingrType: "vegetable",
amount: "1",
amountType: "tsp",
cal: "1",
},
ingr3: {
name: "Garlic",
ingrType: "vegetable",
amount: "1/2",
amountType: "tsp",
cal: "20",
},
ingr4: {
name: "Soy Sauce",
ingrType: "other",
amount: "1/4",
amountType: "tsp",
cal: "20",
},
ingr5: {
name: "Beef",
ingrType: "meat",
amount: "3/4",
amountType: "lbs",
cal: "200",
},
ingr6: {
name: "Salt",
ingrType: "other",
amount: "1/8",
amountType: "tsp",
cal: "0",
},
ingr7: {
name: "Pepper",
ingrType: "other",
amount: "1/8",
amountType: "tsp",
cal: "2",
},
},
Spaghetti: {
ingr1: {
Name: "Ground Beef",
ingrType: "meat",
amount: "1",
amountType: "lbs",
cal: "300",
},
ingr2: {
name: "Olive Oil",
ingrType: "other",
amount: "3",
amountType: "tbsp",
cal: "50",
},
ingr3: {
name: "Onion",
ingrType: "vegetable",
amount: "1",
amountType: "cup",
cal: "30",
},
ingr4: {
name: "Garlic",
ingrType: "vegetable",
amount: "1",
amountType: "tbsp",
cal: "5",
},
ingr5: {
name: "Tomato Paste",
ingrType: "other",
amount: "2",
amountType: "tbsp",
cal: "60",
},
ingr6: {
name: "Dried Oregano",
ingrType: "vegetable",
amount: "1/2",
amountType: "tsp",
cal: "5",
},
ingr7: {
name: "Red Pepper Flakes",
ingrType: "other",
amount: "1",
amountType: "tsp",
cal: "2",
},
ingr8: {
Name: "Red Wine",
ingrType: "other",
amount: "1",
amountType: "cup",
cal: "200",
},
ingr9: {
name: "Tomatoes",
ingrType: "vegetable",
amount: "28",
amountType: "ounce",
cal: "150",
},
ingr10: {
name: "Black Pepper",
ingrType: "other",
amount: "1",
amountType: "tsp",
cal: "2",
},
ingr11: {
name: "Basil Leaves",
ingrType: "vegetable",
amount: "5",
amountType: "pcs",
cal: "5",
},
ingr12: {
name: "Pasta",
ingrType: "other",
amount: "12",
amountType: "ounce",
cal: "250",
},
ingr13: {
name: "Parmesan Cheese",
ingrType: "other",
amount: "1/2",
amountType: "cup",
cal: "75",
},
},
Sushi: {
ingr1: {
Name: "nori",
ingrType: "other",
amount: "6",
amountType: "sheet",
cal: "10",
},
ingr2: {
name: "Sushi Rice",
ingrType: "vegetable",
amount: "3",
amountType: "cup",
cal: "150",
},
ingr3: {
name: "Salmon",
ingrType: "meat",
amount: "1/2",
amountType: "lbs",
cal: "220",
},
ingr4: {
name: "Cream Cheese",
ingrType: "other",
amount: "4",
amountType: "oz",
cal: "75",
},
ingr5: {
name: "Avocado",
ingrType: "fruit",
amount: "1",
amountType: "pc",
cal: "60",
},
ingr6: {
name: "Soy Sauce",
ingrType: "other",
amount: "1",
amountType: "tsp",
cal: "10",
},
},
Burger: {
ingr1: {
Name: "Beef",
ingrType: "meat",
amount: "1",
amountType: "lbs",
cal: "300",
},
ingr2: {
name: "Egg",
ingrType: "other",
amount: "1",
amountType: "large",
cal: "50",
},
ingr3: {
name: "Onion",
ingrType: "vegetable",
amount: "1/2",
amountType: "cup",
cal: "30",
},
ingr4: {
name: "Garlic",
ingrType: "vegetable",
amount: "2",
amountType: "pcs",
cal: "10",
},
ingr5: {
name: "Bread Crumbs",
ingrType: "other",
amount: "1/4",
amountType: "cup",
cal: "60",
},
ingr6: {
name: "Worcestershire",
ingrType: "other",
amount: "1",
amountType: "tbsp",
cal: "5",
},
ingr7: {
name: "Salt",
ingrType: "other",
amount: "1/2",
amountType: "tsp",
cal: "2",
},
ingr8: {
Name: "Pepper",
ingrType: "other",
amount: "1/4",
amountType: "tsp",
cal: "4",
},
ingr9: {
name: "Buns",
ingrType: "other",
amount: "4",
amountType: "pcs",
cal: "150",
},
ingr10: {
name: "Mayonnaise",
ingrType: "other",
amount: "1/4",
amountType: "cup",
cal: "60",
},
ingr11: {
name: "Ketchup",
ingrType: "other",
amount: "1/4",
amountType: "cup",
cal: "25",
},
ingr12: {
name: "Lettuce",
ingrType: "vegetable",
amount: "4",
amountType: "pcs",
cal: "100",
},
ingr13: {
name: "Tomato",
ingrType: "vegetable",
amount: "1",
amountType: "large",
cal: "45",
},
ingr14: {
name: "Red Onion",
ingrType: "vegetable",
amount: "4",
amountType: "slices",
cal: "50",
},
},
};
editIngrList = document.getElementById("edit-ingr-list");
createIngrList(mealObj);
function createIngrList(ingrList) {
for (let i = 0; i < Object.keys(ingrList).length; i++) {
let ingrListBtn = document.createElement("button");
ingrListBtnText = ingrList[Object.keys(ingrList)[i]].name;
ingrListBtn.innerHTML = ingrListBtnText;
editIngrList.appendChild(ingrListBtn);
ingrListBtn.classList.add("edit-ingr-item");
}
return ingrList;
}
<div id="edit-ingr-list"></div>
Upvotes: 0
Views: 163
Reputation: 19787
If you can, I'd modify the JSON. You have an array of dishes that contain an array of ingredients.
Making those changes, it's a simple matter of iterating the arrays.
If you just want to display a list of all ingredients then iterate again, holding found elements in an array and checking if they exist.
const mealsObj = [{
name: "Steak",
ingredients: [{
name: "Butter",
ingrType: "other",
amount: "2",
amountType: "tbsp",
cal: "10",
},
{
name: "Parsley",
ingrType: "vegetable",
amount: "1",
amountType: "tsp",
cal: "1",
},
{
name: "Garlic",
ingrType: "vegetable",
amount: "1/2",
amountType: "tsp",
cal: "20",
},
{
name: "Soy Sauce",
ingrType: "other",
amount: "1/4",
amountType: "tsp",
cal: "20",
},
{
name: "Beef",
ingrType: "meat",
amount: "3/4",
amountType: "lbs",
cal: "200",
},
{
name: "Salt",
ingrType: "other",
amount: "1/8",
amountType: "tsp",
cal: "0",
},
{
name: "Pepper",
ingrType: "other",
amount: "1/8",
amountType: "tsp",
cal: "2",
}
]
},
{
name: "Spaghetti",
ingredients: [{
name: "Ground Beef",
ingrType: "meat",
amount: "1",
amountType: "lbs",
cal: "300",
},
{
name: "Olive Oil",
ingrType: "other",
amount: "3",
amountType: "tbsp",
cal: "50",
},
{
name: "Onion",
ingrType: "vegetable",
amount: "1",
amountType: "cup",
cal: "30",
},
{
name: "Garlic",
ingrType: "vegetable",
amount: "1",
amountType: "tbsp",
cal: "5",
},
{
name: "Tomato Paste",
ingrType: "other",
amount: "2",
amountType: "tbsp",
cal: "60",
},
{
name: "Dried Oregano",
ingrType: "vegetable",
amount: "1/2",
amountType: "tsp",
cal: "5",
},
{
name: "Red Pepper Flakes",
ingrType: "other",
amount: "1",
amountType: "tsp",
cal: "2",
},
{
name: "Red Wine",
ingrType: "other",
amount: "1",
amountType: "cup",
cal: "200",
},
{
name: "Tomatoes",
ingrType: "vegetable",
amount: "28",
amountType: "ounce",
cal: "150",
},
{
name: "Black Pepper",
ingrType: "other",
amount: "1",
amountType: "tsp",
cal: "2",
},
{
name: "Basil Leaves",
ingrType: "vegetable",
amount: "5",
amountType: "pcs",
cal: "5",
},
{
name: "Pasta",
ingrType: "other",
amount: "12",
amountType: "ounce",
cal: "250",
},
{
name: "Parmesan Cheese",
ingrType: "other",
amount: "1/2",
amountType: "cup",
cal: "75",
}
]
}
];
function createRecipies() {
//Create a document framgent so the DOM is only created once
let frag = new DocumentFragment();
//Target element
let editIngrList = document.getElementById("edit-reciepies");
//Go through the meals array
for (var r = 0; r < mealsObj.length; r++) {
let recipie = mealsObj[r];
//Create some DOM elements
let section = document.createElement("section");
let head = document.createElement("h2");
//Create a header
head.innerHTML = recipie.name;
//Append the header to the section
section.appendChild(head);
//Go through the ingredients list
for (var i = 0; i < recipie.ingredients.length; i++) {
//Create the button
var button = document.createElement("button");
button.innerHTML = recipie.ingredients[i].name;
//Append the button to the list
section.appendChild(button);
}
//Update the fragment
frag.appendChild(section);
}
//Finally update the DOM with the fragment.
editIngrList.appendChild(frag);
}
createRecipies();
/*If you just want the ingredients, use an array to hold found elements*/
function createIngredients() {
//Array to hold ingredients
let arrIngredients = [];
//Create a document framgent so the DOM is only created once
let frag = new DocumentFragment();
//Target element
let editIngrList = document.getElementById("edit-ingr-list");
//Go through the meals array
for (var r = 0; r < mealsObj.length; r++) {
let recipie = mealsObj[r];
//Go through the ingredients list
for (var i = 0; i < recipie.ingredients.length; i++) {
//Check if not in ingredients array
if(!arrIngredients.includes(recipie.ingredients[i].name))
{
//Add to ingredients array
arrIngredients.push(recipie.ingredients[i].name);
//Create the button
var button = document.createElement("button");
button.innerHTML = recipie.ingredients[i].name;
//Append the button to fragment
frag.appendChild(button);
}
}
}
//Finally update the DOM with the fragment.
editIngrList.appendChild(frag);
}
createIngredients();
<div id="edit-reciepies"></div>
<h2>Ingredient List</h2>
<div id="edit-ingr-list"></div>
Upvotes: 1
Reputation: 153
const mealToArray = Object.values(mealObj).flatMap((x) => Object.values(x));
createIngrList(mealToArray);
function createIngrList(ingrList) {
for (const ingredient of ingrList) {
let ingrListBtn = document.createElement("button");
ingrListBtn.textContent = ingredient.name;
editIngrList.appendChild(ingrListBtn);
ingrListBtn.classList.add("edit-ingr-item");
}
return ingrList;
}
Upvotes: 2
Reputation: 8610
I think this may be what you are looking for... Though you mention not parsing ingredients that are listed twice, though each food, only has an ingredient listed in your object once. Correct me if I am wrong I will refine answer.
You can use for/in loops to get the nested ingredients and their foods. Then use the obj.name
to get the name. Through the first for/in loop the key -> i
will be the name of the food, then use the second key along witht he first to get the actual .name
=> obj[i][k].name
this will give you the ingredient name.
I also created a couple of divs to palce the food and its buttons wrapped in divs for styling, etc...
You can use conditionals to filter by food if you want to only show a certain type of foods ingredients as buttons.
NOTE: your obj key for the first value is uppercase, this will cause issues when parsing obj[index][key].name
, likely that is just a typo...
Steak: {
ingr1: {
Name: "Butter",
where as the other are lowercase
ingr2: {
name: "Parsley",
mealObj = {
Steak: {
ingr1: {
name: "Butter",
ingrType: "other",
amount: "2",
amountType: "tbsp",
cal: "10",
},
ingr2: {
name: "Parsley",
ingrType: "vegetable",
amount: "1",
amountType: "tsp",
cal: "1",
},
ingr3: {
name: "Garlic",
ingrType: "vegetable",
amount: "1/2",
amountType: "tsp",
cal: "20",
},
ingr4: {
name: "Soy Sauce",
ingrType: "other",
amount: "1/4",
amountType: "tsp",
cal: "20",
},
ingr5: {
name: "Beef",
ingrType: "meat",
amount: "3/4",
amountType: "lbs",
cal: "200",
},
ingr6: {
name: "Salt",
ingrType: "other",
amount: "1/8",
amountType: "tsp",
cal: "0",
},
ingr7: {
name: "Pepper",
ingrType: "other",
amount: "1/8",
amountType: "tsp",
cal: "2",
},
},
Spaghetti: {
ingr1: {
Name: "Ground Beef",
ingrType: "meat",
amount: "1",
amountType: "lbs",
cal: "300",
},
ingr2: {
name: "Olive Oil",
ingrType: "other",
amount: "3",
amountType: "tbsp",
cal: "50",
},
ingr3: {
name: "Onion",
ingrType: "vegetable",
amount: "1",
amountType: "cup",
cal: "30",
},
ingr4: {
name: "Garlic",
ingrType: "vegetable",
amount: "1",
amountType: "tbsp",
cal: "5",
},
ingr5: {
name: "Tomato Paste",
ingrType: "other",
amount: "2",
amountType: "tbsp",
cal: "60",
},
ingr6: {
name: "Dried Oregano",
ingrType: "vegetable",
amount: "1/2",
amountType: "tsp",
cal: "5",
},
ingr7: {
name: "Red Pepper Flakes",
ingrType: "other",
amount: "1",
amountType: "tsp",
cal: "2",
},
ingr8: {
Name: "Red Wine",
ingrType: "other",
amount: "1",
amountType: "cup",
cal: "200",
},
ingr9: {
name: "Tomatoes",
ingrType: "vegetable",
amount: "28",
amountType: "ounce",
cal: "150",
},
ingr10: {
name: "Black Pepper",
ingrType: "other",
amount: "1",
amountType: "tsp",
cal: "2",
},
ingr11: {
name: "Basil Leaves",
ingrType: "vegetable",
amount: "5",
amountType: "pcs",
cal: "5",
},
ingr12: {
name: "Pasta",
ingrType: "other",
amount: "12",
amountType: "ounce",
cal: "250",
},
ingr13: {
name: "Parmesan Cheese",
ingrType: "other",
amount: "1/2",
amountType: "cup",
cal: "75",
},
},
Sushi: {
ingr1: {
Name: "nori",
ingrType: "other",
amount: "6",
amountType: "sheet",
cal: "10",
},
ingr2: {
name: "Sushi Rice",
ingrType: "vegetable",
amount: "3",
amountType: "cup",
cal: "150",
},
ingr3: {
name: "Salmon",
ingrType: "meat",
amount: "1/2",
amountType: "lbs",
cal: "220",
},
ingr4: {
name: "Cream Cheese",
ingrType: "other",
amount: "4",
amountType: "oz",
cal: "75",
},
ingr5: {
name: "Avocado",
ingrType: "fruit",
amount: "1",
amountType: "pc",
cal: "60",
},
ingr6: {
name: "Soy Sauce",
ingrType: "other",
amount: "1",
amountType: "tsp",
cal: "10",
},
},
Burger: {
ingr1: {
Name: "Beef",
ingrType: "meat",
amount: "1",
amountType: "lbs",
cal: "300",
},
ingr2: {
name: "Egg",
ingrType: "other",
amount: "1",
amountType: "large",
cal: "50",
},
ingr3: {
name: "Onion",
ingrType: "vegetable",
amount: "1/2",
amountType: "cup",
cal: "30",
},
ingr4: {
name: "Garlic",
ingrType: "vegetable",
amount: "2",
amountType: "pcs",
cal: "10",
},
ingr5: {
name: "Bread Crumbs",
ingrType: "other",
amount: "1/4",
amountType: "cup",
cal: "60",
},
ingr6: {
name: "Worcestershire",
ingrType: "other",
amount: "1",
amountType: "tbsp",
cal: "5",
},
ingr7: {
name: "Salt",
ingrType: "other",
amount: "1/2",
amountType: "tsp",
cal: "2",
},
ingr8: {
Name: "Pepper",
ingrType: "other",
amount: "1/4",
amountType: "tsp",
cal: "4",
},
ingr9: {
name: "Buns",
ingrType: "other",
amount: "4",
amountType: "pcs",
cal: "150",
},
ingr10: {
name: "Mayonnaise",
ingrType: "other",
amount: "1/4",
amountType: "cup",
cal: "60",
},
ingr11: {
name: "Ketchup",
ingrType: "other",
amount: "1/4",
amountType: "cup",
cal: "25",
},
ingr12: {
name: "Lettuce",
ingrType: "vegetable",
amount: "4",
amountType: "pcs",
cal: "100",
},
ingr13: {
name: "Tomato",
ingrType: "vegetable",
amount: "1",
amountType: "large",
cal: "45",
},
ingr14: {
name: "Red Onion",
ingrType: "vegetable",
amount: "4",
amountType: "slices",
cal: "50",
},
},
};
editIngrList = document.getElementById("edit-ingr-list");
createIngrList(mealObj);
function createIngrList(ingrList) {
for (let i in ingrList) {
let food = document.createElement('DIV')
food.classList.add('foodHeading')
food.textContent = i
editIngrList.append(food)
let ing = document.createElement('DIV')
ing.classList.add('buttons')
food.append(ing)
for (let k in ingrList[i]) {
if (ingrList[i][k].name !== undefined) {
let ingrListBtn = document.createElement("button");
ingrListBtn.textContent = ingrList[i][k].name
ing.append(ingrListBtn)
ingrListBtn.classList.add("edit-ingr-item")
}
}
}
}
.foodHeading {
font-weight: bold;
margin-bottom: .5rem;
font-family: sans-serif;
}
.buttons {
margin-top: .3rem;
}
<div id="edit-ingr-list"></div>
Upvotes: 1