Search code examples
javascriptjqueryapifor-loopdynamic-variables

How to make a dynamic variable in a for loop for javascript for a json return?


The API I'm calling has a section of Ingredients I need to pull, and then push to the html page. They are listed as strIngredient1, strIngredient2, strIngredient3... Until 15. What I want to do is loop through each ingredient? I need some sort of dynamic variable I think. Totally not sure.

for (var x = 1; x < 16; x++) {
  if ((drinkResponse.drinks[0].strIngredient + x) !== null) {
    $("#drinkOutput").append($("<p class='drinkData'>Drink Ingredient" + x + " : " + (drinkResponse.drinks[0].strIngredient + x) + "</p>"))
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>

This is the idea of what I want to do, but currently it returns NaN; when it should be returning a string.

JSON return:

drinks[0] {

  dateModified: "2017-09-02 16:38:19"

  idDrink: "11224"

  strAlcoholic: "Alcoholic"

  strCategory: "Ordinary Drink"

  strCreativeCommonsConfirmed: "No"

  strDrink: "Casino Royale"

  strDrinkAlternate: null

  strDrinkDE: null

  strDrinkES: null

  strDrinkFR: null

  strDrinkThumb: "https://www.thecocktaildb.com/images/media/drink/3qpv121504366699.jpg"

  strDrinkZH-HANS: null

  strDrinkZH-HANT: null

  strGlass: "Whiskey sour glass"

  strIBA: null

  strIngredient1: "Gin"

  strIngredient2: "Lemon juice"

  strIngredient3: "Maraschino liqueur"

  strIngredient4: "Orange bitters"

  strIngredient5: "Egg yolk"

  strIngredient6: null

  strIngredient7: null

  strIngredient8: null

  strIngredient9: null

  strIngredient10: null

  strIngredient11: null

  strIngredient12: null

  strIngredient13: null

  strIngredient14: null

  strIngredient15: null

  strInstructions: "In a shaker half-filled with ice cubes, combine all of the ingredients. Shake well. Strain into a sour glass."

  strInstructionsDE: "In einem Shaker, der halb mit Eiswürfeln gefüllt ist, alle Zutaten vermengen. Gut schütteln. In ein Sour Glas abseihen."

  strInstructionsES: null

  strInstructionsFR: null

  strInstructionsZH-HANS: null

  strInstructionsZH-HANT: null

  strMeasure1: "2 oz "

  strMeasure2: "1/2 oz "

  strMeasure3: "1 tsp "

  strMeasure4: "1 dash "

  strMeasure5: "1 "

  strMeasure6: null

  strMeasure7: null

  strMeasure8: null

  strMeasure9: null

  strMeasure10: null

  strMeasure11: null

  strMeasure12: null

  strMeasure13: null

  strMeasure14: null

  strMeasure15: null

  strTags: null

  strVideo: null

}


Solution

  • You are trying to append to the variable name with the value of x. You're close, but you need to use bracket notation rather than dot notation.

    For example, if x is currently 5, you can get the value of strIngredient5 with drinkResponse.drinks[0]['strIngredient'+x] or drinkResponse.drinks[0][`strIngredient${x}`].

    As Lain pointed out, you can also use Object.keys to enumerate all of the keys on the object, then filter for only the keys which start with strIngredient:

    // get all keys on the drink
    const allKeys = Object.keys(drinkResponse.drinks[0]);
    
    // now filter for only keys starting with `strIngredient`
    const ingredients = allKeys.filter(key => key.startsWith('strIngredient'));
    
    for (const i=0; i<ingredients.length; i++) {
        $("#drinkOutput").append($("<p class='drinkData'>Drink Ingredient" 
        + i + " : " + (drinkResponse.drinks[0][ingredients[i]]) + "</p>"))
    }
    

    Note that this may not preserve the order, but you can preserve the order by combining the first two examples:

    for (const i=0; i<ingredients.length; i++) {
        $("#drinkOutput").append($("<p class='drinkData'>Drink Ingredient" 
        + i + " : " + (drinkResponse.drinks[0][`strIngredient${i}`]) + "</p>"))
    }