Travaille actuellement sur une application Web utilisée pour rechercher des recettes de boissons. L'idée est de rechercher une boisson et d'afficher le nom, les ingrédients et les mesures à l'utilisateur. J'ai du mal à trouver un moyen efficace de parcourir la réponse de l'API car ils ne reviennent pas sous forme de tableau. Voici un exemple de réponse.

dateModified :"2015-08-18 14:54:32"   
idDrink:"11668"    
strAlcoholic:"Alcoholic
strCategory:"Ordinary Drink"
strDrink: "Long Island Tea"
strDrinkThumb:  "https://www.thecocktaildb.com/images/media/drink/ywxwqs1439906072.jpg"
strGlass: "Highball glass"
strIBA:null
strIngredient1: "Vodka"
strIngredient2:"Light rum"
strIngredient3:"Gin" 
strIngredient4:"Tequila"  
strIngredient5: "Lemon"
strIngredient6: "Coca-Cola" 
strIngredient7:""
strIngredient8:""
strIngredient9:""
strIngredient10:""
strIngredient11:""
strIngredient12:""
strIngredient13:""
strIngredient14:""
strIngredient15:""
strInstructions: 
"Combine all ingredients (except cola) and pour over ice in a highball glass. Add the splash of cola for color. Decorate with a slice of lemon and serve." 
strMeasure1:"1/2 oz "
strMeasure2:"1/2 oz "
strMeasure3: "1/2 oz "
strMeasure4: "1/2 oz "
strMeasure5:"Juice of 1/2 "
strMeasure6:"1 splash "
strMeasure7:" "
strMeasure8:" "
strMeasure9:" "
strMeasure10:" "
strMeasure11:" "
strMeasure12:" "
strMeasure13:" "
strMeasure14:" "
strMeasure15:" "
strVideo: null

Le but est de mapper certaines informations sur une table. ou est la meilleure solution pour créer un fichier séparé pour formater les ingrédients?

Actuellement, le chemin de moindre résistance auquel je peux penser est de créer les 15 fois suivantes:
strIngredient1 !=""

Voici l'appel de l'API:

  $('#drinkSearch').click(function(){
var word = document.getElementById("sbar").value;
event.preventDefault();
console.log(word)

  $.getJSON("https://www.thecocktaildb.com/api/json/v1/1/search.php?s="+ word, function(Result) {
    console.log(Result)

    Result.drinks.forEach(function(ingredients){
       var ing1 = ingredients.strIngredient1;
       console.log(ing1);

    })
  });
1
eGathergood 14 avril 2018 à 23:39

3 réponses

Meilleure réponse

L'API renvoie un objet pour chaque boisson avec des clés comme strIngredient1 à strIngredient15, strMeasure1 à strMeasure15, etc. - en effet mal conçues.

Vous pouvez rassembler tout cela dans un tableau. Il existe deux approches différentes pour gérer les valeurs vides. Vous pouvez filtrer simplement les valeurs vides ou faire correspondre les mesures à leurs ingrédients :

Filtrez simplement les valeurs vides

Ces approches suppriment simplement les valeurs vides de chaque tableau à construire. Cela peut entraîner des incohérences, car les clés strMeasure dépendent en fait des clés strIngredient, positionnellement . Recherchez l'approche correspondante ci-dessous pour résoudre ce problème.

Un autre problème est que les ingrédients et les mesures peuvent parfois être en panne. L'approche correspondance ne présente pas ce problème.

Result.drinks.forEach((drink) => {
  const drinkEntries = Object.entries(drink),
    ingredientsArray = drinkEntries
      .filter(([key, value]) => key.startsWith("strIngredient") && value && value.trim())
      .map(([key, value]) => value),
    measuresArray = drinkEntries
      .filter(([key, value]) => key.startsWith("strMeasure") && value && value.trim())
      .map(([key, value]) => value);

  console.log("Ingredients:", ingredientsArray);
  console.log("Measures:", measuresArray);
});

Dans le filter, key.startsWith("strIngredient") garantit que vous obtenez les quinze bonnes clés et && value && value.trim() garantit que la valeur n'est ni null, ni vide, ni simplement des espaces (d'où trim). Les trois variantes sont utilisées de manière aléatoire.

Un formulaire moins redondant pourrait ressembler à ceci:

Result.drinks.forEach((drink) => {
  const drinkEntries = Object.entries(drink),
    [
      ingredientsArray,
      measuresArray
    ] = [
      "strIngredient",
      "strMeasure"
    ].map((keyName) => drinkEntries
      .filter(([key, value]) => key.startsWith(keyName) && value && value.trim())
      .map(([key, value]) => value));

  console.log("Ingredients:", ingredientsArray);
  console.log("Measures:", measuresArray);
});

Adapter les mesures à leurs ingrédients

Cette approche crée d'abord deux tableaux pour les strIngredient et les strMeasure. Les clés numériques sont extraites avec parseInt(key.slice(keyName.length)). Object.assign ing plusieurs {key: value} objets sur un tableau, où key sont numériques, signifie construire un tableau avec ces clés numériques et ces valeurs. 1

Ensuite, les valeurs sont filtrées de telle sorte qu'elles restent si toute valeur avec le même index n'est pas vide.

Result.drinks.forEach((drink) => {
  const drinkEntries = Object.entries(drink),
    // This part build arrays out of the two sets of keys
    [
      ingredientsArray,
      measuresArray
    ] = [
      "strIngredient",
      "strMeasure"
    ].map((keyName) => Object.assign([], ...drinkEntries
        .filter(([key, value]) => key.startsWith(keyName))
        .map(([key, value]) => ({[parseInt(key.slice(keyName.length))]: value})))),

    // This part filters empty values based on the ingredients
    {
      finalIngredients,
      finalMeasures
    } = ingredientsArray.reduce((results, value, index) => {
      if(value && value.trim() || measuresArray[index] && measuresArray[index].trim()){
        results.finalIngredients.push(value);
        results.finalMeasures.push(measuresArray[index]);
      }

      return results;
    }, {
      finalIngredients: [],
      finalMeasures: []
    }),

    // Optional: zip both arrays
    ingredientsWithMeasures = finalIngredients
      .map((value, index) => [finalMeasures[index], value]);

  // Output
  console.log("Ingredients:", finalIngredients);
  console.log("Measures:", finalMeasures);

  console.log("All ingredients and measures:\n", ingredientsWithMeasures
    .map(([measure, ingredient]) => `${(measure || "").trim()} ${(ingredient || "").trim()}`)
    .join("\n"));
});

1 : la construction d'un tableau à partir d'objets fonctionne également souvent avec Array.from, mais cela nécessite également une propriété length. Au lieu de calculer cela, je suis simplement allé de l'avant et j'ai utilisé Object.assign à la place.

3
user4642212 14 avril 2018 à 22:50

J'aime la réponse de Xufox, voici une autre possibilité d'apprivoiser cette API, avec un appel codé en dur pour un manhattan :) L'idée ici est de rassembler diverses choses dans un recipe final qui contient les données utiles.

NB J'ai refactorisé ceci pour montrer comment vous pouvez (et devriez peut-être) extraire votre mappage dans une fonction distincte.

const word = 'manhattan';
const url = `https://www.thecocktaildb.com/api/json/v1/1/search.php?s=${word}`;


$.getJSON(url, (result) => {
  const recipes = result.drinks.map(extractRecipe);
  console.log(recipes);
})

// do your mapping in a defined function.
function extractRecipe(drink) {
  const recipe = {
    name: drink.strDrink,
    glass: drink.strGlass,
    instructions: drink.strInstructions,
    thumbnail: drink.strDrinkThumb
  };

  Object.keys(drink)
    .filter(key => key.substring(0, 13) === 'strIngredient')
    .filter(key => drink[key].trim())
    .reduce((ingredients, ingredient) => ingredients.concat(ingredient), [])
    .forEach((key, index) => {
      let ingIndex = index + 1;
      recipe[drink[key]] = drink[`strMeasure${ingIndex}`];
    })
  return recipe;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
0
Matt Morgan 14 avril 2018 à 21:37

Une solution alternative peut être:

result.drinks.forEach(function(ingredients){
   var ing = Object.keys(ingredients).reduce(function(a, ele) {
       if (ele.startsWith('strIngredient') && ingredients[ele].trim() != '') {
           if (!a[ingredients.strDrink]) a[ingredients.strDrink] = [];
           a[ingredients.strDrink].push(ingredients[ele]);
       }
       return a;
   }, {});
   console.log(Object.keys(ing)[0] + ': ' + ing[Object.keys(ing)[0]].join(', '));

})

var result= {
    "drinks": [{
        "idDrink": "12734",
        "strDrink": "Chocolate Drink",
        "strVideo": null,
        "strCategory": "Cocoa",
        "strIBA": null,
        "strAlcoholic": "Non alcoholic",
        "strGlass": "Coffee mug",
        "strInstructions": "Melt the bar in a small amount of boiling water. Add milk. Cook over low heat, whipping gently (with a whisk, i would assume) until heated well. Don't let it boil! Serve in coffee mug.",
        "strDrinkThumb": "https:\/\/www.thecocktaildb.com\/images\/media\/drink\/q7w4xu1487603180.jpg",
        "strIngredient1": "Chocolate",
        "strIngredient2": "Milk",
        "strIngredient3": "Water",
        "strIngredient4": "",
        "strIngredient5": "",
        "strIngredient6": "",
        "strIngredient7": "",
        "strIngredient8": "",
        "strIngredient9": "",
        "strIngredient10": "",
        "strIngredient11": "",
        "strIngredient12": "",
        "strIngredient13": "",
        "strIngredient14": "",
        "strIngredient15": "",
        "strMeasure1": "125 gr",
        "strMeasure2": "3\/4 L ",
        "strMeasure3": "",
        "strMeasure4": "",
        "strMeasure5": "",
        "strMeasure6": "",
        "strMeasure7": "",
        "strMeasure8": "",
        "strMeasure9": "",
        "strMeasure10": "",
        "strMeasure11": "",
        "strMeasure12": "",
        "strMeasure13": "",
        "strMeasure14": "",
        "strMeasure15": "",
        "dateModified": "2017-02-20 15:06:20"
    }, {
        "idDrink": "12736",
        "strDrink": "Drinking Chocolate",
        "strVideo": null,
        "strCategory": "Cocoa",
        "strIBA": null,
        "strAlcoholic": "Non alcoholic",
        "strGlass": "Coffee mug",
        "strInstructions": "Heat the cream and milk with the cinnamon and vanilla bean very slowly for 15-20 minutes. (If you don't have any beans add 1-2 tsp of vanilla after heating). Remove the bean and cinnamon. Add the chocolate. Mix until fully melted. Serve topped with some very dense fresh whipped cream. Serves 1-2 depending upon how much of a glutton you are. For a richer chocolate, use 4 oz of milk, 4 oz of cream, 4 oz of chocolate. Serve in coffee mug.",
        "strDrinkThumb": "https:\/\/www.thecocktaildb.com\/images\/media\/drink\/u6jrdf1487603173.jpg",
        "strIngredient1": "Heavy cream",
        "strIngredient2": "Milk",
        "strIngredient3": "Cinnamon",
        "strIngredient4": "Vanilla",
        "strIngredient5": "Chocolate",
        "strIngredient6": "Whipped cream",
        "strIngredient7": "",
        "strIngredient8": "",
        "strIngredient9": "",
        "strIngredient10": "",
        "strIngredient11": "",
        "strIngredient12": "",
        "strIngredient13": "",
        "strIngredient14": "",
        "strIngredient15": "",
        "strMeasure1": "2 oz ",
        "strMeasure2": "6-8 oz ",
        "strMeasure3": "1 stick ",
        "strMeasure4": "1 ",
        "strMeasure5": "2 oz finely chopped dark ",
        "strMeasure6": "Fresh ",
        "strMeasure7": " ",
        "strMeasure8": " ",
        "strMeasure9": " ",
        "strMeasure10": " ",
        "strMeasure11": " ",
        "strMeasure12": "",
        "strMeasure13": "",
        "strMeasure14": "",
        "strMeasure15": "",
        "dateModified": "2017-02-20 15:06:13"
    }, {
        "idDrink": "12690",
        "strDrink": "Lassi - A South Indian Drink",
        "strVideo": null,
        "strCategory": "Other\/Unknown",
        "strIBA": null,
        "strAlcoholic": "Non alcoholic",
        "strGlass": "Highball Glass",
        "strInstructions": "Blend in a blender for 3 seconds. Lassi is one of the easiest things to make, and there are many ways of making it. Basically, it is buttermilk (yoghurt whisked with water), and you can choose almost any consistency that you like, from the thinnest to the thickest. Serve cold.",
        "strDrinkThumb": "https:\/\/www.thecocktaildb.com\/images\/media\/drink\/iq6scx1487603980.jpg",
        "strIngredient1": "Yoghurt",
        "strIngredient2": "Water",
        "strIngredient3": "Cumin seed",
        "strIngredient4": "Salt",
        "strIngredient5": "Mint",
        "strIngredient6": "",
        "strIngredient7": "",
        "strIngredient8": "",
        "strIngredient9": "",
        "strIngredient10": "",
        "strIngredient11": "",
        "strIngredient12": "",
        "strIngredient13": "",
        "strIngredient14": "",
        "strIngredient15": "",
        "strMeasure1": "1\/2 cup plain ",
        "strMeasure2": "1 1\/4 cup cold ",
        "strMeasure3": "1\/2 tsp ground roasted ",
        "strMeasure4": "1\/4 tsp ",
        "strMeasure5": "1\/4 tsp dried ",
        "strMeasure6": " ",
        "strMeasure7": " ",
        "strMeasure8": " ",
        "strMeasure9": " ",
        "strMeasure10": " ",
        "strMeasure11": "",
        "strMeasure12": "",
        "strMeasure13": "",
        "strMeasure14": "",
        "strMeasure15": "",
        "dateModified": "2017-02-20 15:19:40"
    }]
};

result.drinks.forEach(function(ingredients){
    var ing = Object.keys(ingredients).reduce(function(a, ele) {
        if (ele.startsWith('strIngredient') && ingredients[ele].trim() != '') {
            if (!a[ingredients.strDrink]) a[ingredients.strDrink] = [];
            a[ingredients.strDrink].push(ingredients[ele]);
        }
        return a;
    }, {});
    console.log(Object.keys(ing)[0] + ': ' + ing[Object.keys(ing)[0]].join(', '));

})
0
gaetanoM 14 avril 2018 à 21:17