Search code examples
javascriptjsonexpress

How to loop through JSON Object to some of key - value pair which are related in key-name


Hello My fellow programmers, am trying to get Data from this API URL "www.thecocktaildb.com/api/json/v1/1/random.php" by using express (node.js) in my back-end codes, and the response. Data from an API is as follows.

{
    "drinks": [
        {
            "idDrink": "13206",
            "strDrink": "Caipirissima",
            "strDrinkAlternate": null,
            "strTags": null,
            "strVideo": null,
            "strCategory": "Ordinary Drink",
            "strIBA": null,
            "strAlcoholic": "Alcoholic",
            "strGlass": "Collins Glass",
            "strInstructions": "Same as Caipirinha but instead of cachaca you add WHITE RUM. It's great!!!!!!!!",
            "strInstructionsES": "Igual que la Caipirinha pero en vez de cachaca se le añade RON BLANCO. ¡¡¡¡¡¡¡¡Es genial!!!!!!!!",
            "strInstructionsDE": "Wie Caipirinha, aber anstelle von Cachaca fügen Sie WHITE RUM hinzu. Es ist großartig!!!!!!!!",
            "strInstructionsFR": "Identique à la Caipirinha, mais au lieu de la cachaca, on ajoute du rhum blanc. C'est génial !!!!!!!!",
            "strInstructionsIT": "Come la Caipirinha ma al posto della cachaca aggiungi del rum bianco.\r\nÈ ottimo!",
            "strInstructionsZH-HANS": null,
            "strInstructionsZH-HANT": null,
            "strDrinkThumb": "https://www.thecocktaildb.com/images/media/drink/yd47111503565515.jpg",
            "strIngredient1": "Lime",
            "strIngredient2": "Sugar",
            "strIngredient3": "White rum",
            "strIngredient4": "Ice",
            "strIngredient5": null,
            "strIngredient6": null,
            "strIngredient7": null,
            "strIngredient8": null,
            "strIngredient9": null,
            "strIngredient10": null,
            "strIngredient11": null,
            "strIngredient12": null,
            "strIngredient13": null,
            "strIngredient14": null,
            "strIngredient15": null,
            "strMeasure1": "2 ",
            "strMeasure2": "2 tblsp ",
            "strMeasure3": "2-3 oz ",
            "strMeasure4": "crushed ",
            "strMeasure5": null,
            "strMeasure6": null,
            "strMeasure7": null,
            "strMeasure8": null,
            "strMeasure9": null,
            "strMeasure10": null,
            "strMeasure11": null,
            "strMeasure12": null,
            "strMeasure13": null,
            "strMeasure14": null,
            "strMeasure15": null,
            "strImageSource": null,
            "strImageAttribution": null,
            "strCreativeCommonsConfirmed": "No",
            "dateModified": "2017-08-24 10:05:15"
        }
    ]
}

My question is, how can I loop through strIngredient1 to strIngredient15 and to skip all keys (strIngredient) containing null values using JavaScript, and show the list of available ingredients in a <li> Tag on .ejs file

My .js file looks like this:

import express from "express";
import axios from "axios";
import bodyParser from "body-parser";

const app = express();
const port = 3000;

app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static("public"));

const API_URL = "https://thecocktaildb.com/api/json/v1/1/random.php";

app.get("/", async (req, res) => {
  try {
    const response = await axios.get(API_URL);
    const results = response.data;
    console.log(results.drinks[0].strDrink);
    res.render("index.ejs", { cocktailData: results.drinks[0] });
  } catch (error) {
    console.log(error.response);
    res.status(500);
  }
});
app.listen(port, () => {
  console.log(`Server is running at port ${port}`);
});

My .ejs file looks like this:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Cocktail 🍹</title>
  </head>
  <body>
    <h1>Welcome to the Cocktail Application Center</h1>
    <img src="<%= cocktailData.strDrinkThumb %>" alt="" />
    <ul>
      <% for(var i = 1 ; i < 16 ; i++) { %>
      <li><%= cocktailData.strIngredient + [i] %></li>
      <% } %>
    </ul>
  </body>
</html>

I tried to use for loop but I didn't get the right answer


Solution

  • First lets get just the ingredients:

    const ingredients = Object.entries(results.drinks[0])
      .filter(([key, value]) => key.startsWith('strIngredient') && value !== null)
      .map(([key, value]) => value);
    

    Lets turn the JSON object into something iterable we can loop on.

    Object.entries(results.drinks[0])
    

    We use Object.entries to turn the JSON into an array of [key, value] pairs.

    This gives us:

    [
      ["idDrink", "13206"],
      ["strDrink", "Caipirissima"],
      ["strDrinkAlternate", null],
      ...
    ]
    
    .filter(([key, value]) => key.startsWith('strIngredient') && value !== null)
    

    We filter out all keys that don't start with strIngredient, and all values that are null.

    This gives us:

    [
      ["strIngredient1", "Lime"],
      ["strIngredient2", "Sugar"],
      ["strIngredient3", "White rum"],
      ["strIngredient4", "Ice"],
    ]
    
    .map(([key, value]) => value);
    

    Finally we map our results to extract just the values.

    This gives us:

    ["Lime", "Sugar", "White rum", "Ice"]
    

    Now it should be simple to put it in the templating engine:

    <ul>
      <% for (const ingredient of ingredients) { %>
        <li><%= ingredient %></li>
      <% } %>
    </ul>