简体   繁体   中英

How do I loop through data from an API in Javascript?

I'm trying to learn how to grab data several levels in to JSON data coming from APIs, and I'm getting confused on how to do so. For example, I'm trying to create a random meal generator that displays a list of ingredients that is in an array of recipes, but also, the ingredient names I need are in their own object.

I'm not sure how to set up my loop to loop through the list and grab the ingredient name to display it. Here is my example so far: codepen

Thanks!

 document.getElementById("shuffle").addEventListener('click', getImage); async function getImage() { const response = await fetch("https://spoonacular-recipe-food-nutrition-v1.p.rapidapi.com/recipes/random?number=1", { "method": "GET", "headers": { "x-rapidapi-key": "{redacted}", "x-rapidapi-host": "spoonacular-recipe-food-nutrition-v1.p.rapidapi.com" } }) const data = await response.json(); document.getElementById('title').innerHTML = data.recipes[0]["title"]; document.getElementById('instructions').innerHTML = data.recipes[0]["instructions"]; document.getElementById('image').src = data.recipes[0]["image"]; show(data); } getImage().catch(error => { console.error(error); }); function show(data) { let list = ` <ul></ul> ` for (let ingredient of data.recipes) { list += ` <li>${ingredient.extendedIngredients[0].originalString}</li> `; } document.getElementById('ingredients').innerHTML = list; }
 .recipe { display: flex; justify-content: center; align-items: center; flex-direction: column; text-align: center; }.recipe__directions { display: flex; width: 50vw; margin: 2rem; }.recipe__instructions { text-align: left; margin-right: 1rem; }.recipe__image { width: 25vw; margin-left: 1rem; }
 <html> <head> <:-- Material Design Lite --> <script src="https.//code.getmdl.io/1.3.0/material.min:js"></script> <link rel="stylesheet" href="https.//code.getmdl.io/1.3.0/material.indigo-pink.min:css"> <.-- Material Design icon font --> <link rel="stylesheet" href="https.//fonts?googleapis?com/icon?family=Material+Icons"> </head> <body> <section class="recipe"> <h1>Feeling hungry?</h1> <h2>Get a random meal by clicking below</h2> <button class="button mdl-button mdl-js-button mdl-button--raised mdl-button--colored" id="shuffle">Find a meal</button> <h3 id="title" class="recipe__title"></h3> <div id="ingredients" class="recipe__ingredients"></div> <div class="recipe__directions"> <p id="instructions" class="recipe__instructions"></p> <img id="image" class="recipe__image" src="" alt=""> </div> </section> </body> </html>

Use forEach() to loop through each extendedIngredients property.

function show(data) { 
  let list = 
      `
      <ul></ul>
      `
  data.recipes[0].extendedIngredients.forEach( function(ingredient){
        list += `  
    <li>${ingredient.originalString}</li>        
`; 
    });
  
  document.getElementById('ingredients').innerHTML = list;
} 

You were on the right track, but not deep enough. The for loop you wrote is iterating over each recipes , not each extendedIngredients . There is only one recipes so you access it with key [0] .

function show(data) { 
  let list = 
      `
      <ul></ul>
      `
    for (let ingredient of data.recipes[0].extendedIngredients) { 
        list += `  
    <li>${ingredient.originalString}</li>        
`; 
    }
  
  document.getElementById('ingredients').innerHTML = list;
} 
  • if you look at json structure will se that extendedIngredients are an array so, you can loop for each of them
  • You are getting only one recipe at time so no need a loop there...

you can change the loop to:

   for (let ingredient of data.recipes[0].extendedIngredients) { // loop over ingredients of first recipe
            list += `  
        <li>${ingredient.originalString}</li>        
    `; 
        }

 document.getElementById("shuffle").addEventListener('click', getImage); async function getImage() { const response = await fetch("https://spoonacular-recipe-food-nutrition-v1.p.rapidapi.com/recipes/random?number=1", { "method": "GET", "headers": { "x-rapidapi-key": "", "x-rapidapi-host": "" } }) const data = await response.json(); document.getElementById('title').innerHTML = data.recipes[0]["title"]; document.getElementById('instructions').innerHTML = data.recipes[0]["instructions"]; document.getElementById('image').src = data.recipes[0]["image"]; show(data); } getImage().catch(error => { console.error(error); }); function show(data) { let list = ` <ul></ul> ` for (let ingredient of data.recipes[0].extendedIngredients) { // loop over ingredients of first recipe list += ` <li>${ingredient.originalString}</li> `; } document.getElementById('ingredients').innerHTML = list; }
 .recipe { display: flex; justify-content: center; align-items: center; flex-direction: column; text-align: center; }.recipe__directions { display: flex; width: 50vw; margin: 2rem; }.recipe__instructions { text-align: left; margin-right: 1rem; }.recipe__image { width: 25vw; margin-left: 1rem; }
 <html> <head> <:-- Material Design Lite --> <script src="https.//code.getmdl.io/1.3.0/material.min:js"></script> <link rel="stylesheet" href="https.//code.getmdl.io/1.3.0/material.indigo-pink.min:css"> <.-- Material Design icon font --> <link rel="stylesheet" href="https.//fonts?googleapis?com/icon?family=Material+Icons"> </head> <body> <section class="recipe"> <h1>Feeling hungry?</h1> <h2>Get a random meal by clicking below</h2> <button class="button mdl-button mdl-js-button mdl-button--raised mdl-button--colored" id="shuffle">Find a meal</button> <h3 id="title" class="recipe__title"></h3> <div id="ingredients" class="recipe__ingredients"></div> <div class="recipe__directions"> <p id="instructions" class="recipe__instructions"></p> <img id="image" class="recipe__image" src="" alt=""> </div> </section> </body> </html>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM