4
\$\begingroup\$

I'm training JavaScript and using APIs. So I'm building a recipe website that lets you search ingredients and finds you recipes with it.

Here is the link: https://www.themealdb.com/

I found some code I could help myself with, and that I understood, to build on. I then wanted to have a few available Json informations more to be added to what's printed on the website.

I want to have the list of all ingredients and the measures next to it. Now, I have found the info and have extracted it BUT :

  1. the code is redundant
  2. I know you can make it more efficient with a few lines instead of all mine
  3. I have no idea how to implement the forEach loop I think is needed there
  4. it would be prettier if it only printed the ingredients available and not every single ingredient slot there is even if it is empty.

Please help me figure this out. I feel like it's an easy thing that I just can't put my finger on.

Here is the part of my code I want to optimize :

    function mealRecipeModal(meal) {
  console.log(meal);
  meal = meal[0];
  let html = `
        <h2 class = "recipe-title">${meal.strMeal}</h2>
        <p class = "recipe-category">${meal.strCategory}</p>
        <p class = "recipe-category"> ${meal.strArea}</p>
        <div>
            <h3>Ingredients:</h3>
            <p class = "recipe-ingredients">
            ${meal.strIngredient1 + ` ` + meal.strMeasure1} </br>
            ${meal.strIngredient2 + ` ` + meal.strMeasure2}</br>
            ${meal.strIngredient3 + ` ` + meal.strMeasure3}</br>
            ${meal.strIngredient4 + ` ` + meal.strMeasure4}</br>
            ${meal.strIngredient5 + ` ` + meal.strMeasure5}</br>
            ${meal.strIngredient6 + ` ` + meal.strMeasure6}</br>
            ${meal.strIngredient7 + ` ` + meal.strMeasure7}</br>
            ${meal.strIngredient8 + ` ` + meal.strMeasure8}</br>
            ${meal.strIngredient9 + ` ` + meal.strMeasure9}</br>
            ${meal.strIngredient10 + ` ` + meal.strMeasure10}</br>
            ${meal.strIngredient11 + ` ` + meal.strMeasure11}</br>
            ${meal.strIngredient12 + ` ` + meal.strMeasure12}</br>
            ${meal.strIngredient13 + ` ` + meal.strMeasure13}</br>
            ${meal.strIngredient14 + ` ` + meal.strMeasure14}</br>
            ${meal.strIngredient15 + ` ` + meal.strMeasure15}</br>
            ${meal.strIngredient16 + ` ` + meal.strMeasure16}</br>
            ${meal.strIngredient17 + ` ` + meal.strMeasure17}</br>
            ${meal.strIngredient18 + ` ` + meal.strMeasure18}</br>
            ${meal.strIngredient19 + ` ` + meal.strMeasure19}</br>
            ${meal.strIngredient20 + ` ` + meal.strMeasure20}</br>
            </p>
        </div>
        <div class = "recipe-instruct">
            <h3>Instructions:</h3>
            <p>${meal.strInstructions}</p>
        </div>
        <div class = "recipe-link">
            <a href="${meal.strSource}">Source here</a>
        </div>
        <div class = "recipe-meal-img">
            <img src = "${meal.strMealThumb}" alt = "">
        </div>
    `;
  mealDetailsContent.innerHTML = html;
  mealDetailsContent.parentElement.classList.add("showRecipe");
}

And the JSON info looks like this :

dateModified: null
​​
idMeal: "52846"
​​
strArea: "British"
​​
strCategory: "Chicken"
​​
strCreativeCommonsConfirmed: null
​​
strDrinkAlternate: null
​​
strImageSource: null
​​
strIngredient1: "Butter"
​​
strIngredient10: "Potatoes"
​​
strIngredient11: "Butter"
​​
strIngredient12: ""
​​
strIngredient13: ""
​​
strIngredient14: ""
​​
strIngredient15: ""
​​
strIngredient16: ""
​​
strIngredient17: ""
​​
strIngredient18: ""
​​
strIngredient19: ""
​​
strIngredient2: "Onion"
​​
strIngredient20: ""
​​
strIngredient3: "Mushrooms"
​​
strIngredient4: "Plain Flour"
​​
strIngredient5: "Chicken Stock Cube"
​​
strIngredient6: "Nutmeg"
​​
strIngredient7: "Mustard Powder"
​​
strIngredient8: "Chicken"
​​
strIngredient9: "Sweetcorn"
​​
strInstructions: "Heat oven to 200C/180C fan/gas 6. Put the butter in a medium-size saucepan and place over a medium heat. Add the onion and leave to cook for 5 mins, stirring occasionally. Add the mushrooms to the saucepan with the onions.\r\n\r\nOnce the onion and mushrooms are almost cooked, stir in the flour – this will make a thick paste called a roux. If you are using a stock cube, crumble the cube into the roux now and stir well. Put the roux over a low heat and stir continuously for 2 mins – this will cook the flour and stop the sauce from having a floury taste.\r\n\r\nTake the roux off the heat. Slowly add the fresh stock, if using, or pour in 500ml water if you’ve used a stock cube, stirring all the time. Once all the liquid has been added, season with pepper, a pinch of nutmeg and mustard powder. Put the saucepan back onto a medium heat and slowly bring it to the boil, stirring all the time. Once the sauce has thickened, place on a very low heat. Add the cooked chicken and vegetables to the sauce and stir well. Grease a medium-size ovenproof pie dish with a little butter and pour in the chicken and mushroom filling.\r\n\r\nCarefully lay the potatoes on top of the hot-pot filling, overlapping them slightly, almost like a pie top.\r\n\r\nBrush the potatoes with a little melted butter and cook in the oven for about 35 mins. The hot-pot is ready once the potatoes are cooked and golden brown."
​​
strMeal: "Chicken & mushroom Hotpot"
​​
strMealThumb: "https://www.themealdb.com/images/media/meals/uuuspp1511297945.jpg"
​​
strMeasure1: "50g"
​​
strMeasure10: "2 large"
​​
strMeasure11: "1 knob"
​​
strMeasure12: ""
​​
strMeasure13: ""
​​
strMeasure14: ""
​​
strMeasure15: ""
​​
strMeasure16: ""
​​
strMeasure17: ""
​​
strMeasure18: ""
​​
strMeasure19: ""
​​
strMeasure2: "1 chopped"
​​
strMeasure20: ""
​​
strMeasure3: "100g "
​​
strMeasure4: "40g"
​​
strMeasure5: "1"
​​
strMeasure6: "pinch"
​​
strMeasure7: "pinch"
​​
strMeasure8: "250g"
​​
strMeasure9: "2 Handfuls"
​​
strSource: "https://www.bbcgoodfood.com/recipes/chicken-mushroom-hot-pot"
​​
strTags: null
​​
strYoutube: "https://www.youtube.com/watch?v=bXKWu4GojNI"

I hope you have all information available to help me.

So to sum it up : How do I write the best code to only get the ingredients needed for the recipe and not all the empty strings for some extra ingredients in some other recipes?

How do I make it both pretty and functional ? - I want to improve my coding but I'd love it if I could do it by learning best practices at the same time !

\$\endgroup\$
2
  • 1
    \$\begingroup\$ @SᴀᴍOnᴇᴌᴀ hey ! i guess i want both, i'll do that ! well yes its html but it's in a html.innerHTML = {code up there}. I can put more of the code if it helps ? I kind of want a forEach loop that makes it so i dont have alle the lines up there but only one line and the number at the end of both ${meal.strIngredients} and the other one, changes in a n+1 way... does it make sense ? Im so bad at explaining myself.. \$\endgroup\$
    – emma673r
    Commented Aug 11, 2022 at 18:55
  • 1
    \$\begingroup\$ I added the whole javascript function, i can see that i makes more sense, excuse me for the bad formulating. \$\endgroup\$
    – emma673r
    Commented Aug 11, 2022 at 19:00

1 Answer 1

2
\$\begingroup\$

First of all, it's quite a bad idea to code all your HTML in a string like this

element.innerHTML = "<div>${meal.strIngredient1}</div>"

If you code HTML like this, your editor will think you are typing a string and will not give you warnings for syntax errors. (for example if you forget a closing tag). The proper way to do it is:

let div = document.createElement("div")
div.innerText = `${meal.strIngredient8} ${meal.strMeasure8}`
parent.appendChild(div)

(Note that you don't need the + in between the variables.)

Then, you could optimize your JSON by leaving out the variable names:

{ "recipes": [
    { "ingredient" : "basil", "measure" : 3 },
    { "ingredient" : "tyme", "measure" : 4 },
]}

This allows you to create a for loop that can loop over all the recipes like this:

for (let meal of recipes) {
    let div = document.createElement("div")
    div.innerText = `${meal.ingredient} ${meal.measure}`
    parent.appendChild(div)
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.