我开发了一个小的食谱应用程序。这个应用程序使用毛豆API。我实现了一个过滤器函数,可以根据饮食和健康等标准进行过滤。此外,还可以根据卡路里进行过滤。为此,用户可以指定卡路里的最大值,如果他想根据卡路里进行过滤的话。然而,过滤器功能不起作用。2我在过滤器“健康”中输入了“高蛋白”,在搜索栏中输入了“汉堡”。3但是结果没有被过滤。4代码看起来很有用。5希望大家能帮帮我!
这是我的HTML代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Kitchn - Kochen leicht gemacht! </title>
<link href="styles.css" rel="stylesheet">
</head>
<body>
<main class="container">
<div style="text-align: center;">
<e style="margin: 0;" data-i18n-key="languages-title">Sprachen</e>
<div id="languages" class="grid">
<div id="de"></div>
<div id="en"></div>
</div>
<div class = "container" >
<div class = "row" id="photo"><!--collage-->
<div class="col-12" id="logo">
<img src="assets\image-removebg-preview.png" id= "food" class="row"/>
<div><p data-i18n-key="title" id="title">AppName</p></div>
</div>
</div>
</div>
<div class="row" id="search"><!--searchbar-->
<div class="col-8" id="searchbar" >
<img src = "assets\pawprint.png" id="paw"/>
<input placeholder="Vegan, etc." id="input"/>
</div>
<div class="col-2" id="button" >
<img src = "assets\paw.png" id="enter"/>
</div>
</div>
<div class ="row"id = "cards"><!--reccommedned-->
</div> <!--Filterfunktion für Kalorien etc. hier -->
<div class="row" id="filter">
<div class="col-3">
<select id="filter-select">
<option value="diet">Diät</option>
<option value="health">Gesundheit</option>
</select>
</div>
<div class="col-3">
<input type="text" id="filter-value" placeholder="Wert eingeben">
</div>
<div class="col-3">
<button id="submit" onclick="filterRecipes()">Filter anwenden</button>
</div>
<div class="col-3">
<div>Maximale Kalorien:</div>
<input type="text" id="calorie-limit" placeholder="Max. Kalorien">
</div>
</div>
</div>
<script src ="script.js"></script>
</body>
</html>
这是我的JavaScript代码:
const queryBox = document.getElementById("input");
const submit = document.getElementById("button");
submit.addEventListener("click", async function() {
const query = queryBox.value;
const recipes = await getRecipes(query);
useApiData(recipes);
});
document.addEventListener("keypress", async function(e) {
if (e.key === "Enter") {
const query = queryBox.value;
const recipes = await getRecipes(query);
useApiData(recipes);
}
});
const appId = "a59a7160";
const apiKey = "69e96203434da5104b731b2fd8a597b7";
async function getRecipes(query, from = 0, to = 8, diet = [], health = [], maxCalories = Number.POSITIVE_INFINITY) {
let url =`https://api.edamam.com/search?q=${query}&app_id=${appId}&app_key=${apiKey}&from=${from}&to=${to}`
if (diet.length) {
const dietString = diet.join(",");
url+=`&diet=${encodeURIComponent(dietString)}`
}
if (health.length) {
const healthString = health.join(",")
url+=`&health=${encodeURIComponent(healthString)}`
}
if (maxCalories !== Number.POSITIVE_INFINITY) {
url+= `&calories=${maxCalories.toString()}`
}
const response = await fetch(
url
);
const data = await response.json();
return data.hits;
}
function useApiData(data) {
const filteredRecipes = filterRecipes(data);
let toadd = "";
for (let i = 0; i < filteredRecipes.length; i++) {
let diet = "No Data Found";
if (data[i].recipe.dietLabels && Array.isArray(data[i].recipe.dietLabels) && data[i].recipe.dietLabels.length > 0) {
diet = data[i].recipe.dietLabels;
}
let health = "No restrictions";
if (data[i].recipe.healthLabels && Array.isArray(data[i].recipe.healthLabels) && data[i].recipe.healthLabels.length > 0) {
health = data[i].recipe.healthLabels;
}
toadd += `
<div class="card">
<img src="${data[i].recipe.image}" class="card-ing-top" alt="..."/>
<div class="card-body">
<h5 class="card-title">${data[i].recipe.label}</h5>
<a href="${data[i].recipe.url}" class="btn"><b>Click here for full recipe!</a> </b>
<br>
<br>
<r class = "item-data"><b>Calories: </b> <br> ${data[i].recipe.calories.toFixed(2)}</r>
<br>
<r class="item-data"><b>Diet label: </b> <br> ${diet}</r>
<br>
<r class = "item-data"><b>Health label: </b> <br> ${health}</r>
<br>
<r class = "item-data"><b>Ingredient line:</b> <br> ${data[i].recipe.ingredientLines}</r>
</div>
</div>
`
}
document.getElementById("cards").innerHTML = toadd;
}
function filterRecipes(recipes, diet = [], health = []) {
if (diet.length === 0 && health.length === 0) {
return recipes;
}
const filteredRecipes = recipes.filter((recipe) => {
if (diet.length > 0 && recipe.recipe.dietLabels) {
const dietLabels = recipe.recipe.dietLabels.map((label) => label.toLowerCase());
if (!diet.some((d) => dietLabels.includes(d))) {
return false;
}
}
if (health.length > 0 && recipe.recipe.healthLabels) {
const healthLabels = recipe.recipe.healthLabels.map((label) => label.toLowerCase());
if (!health.some((h) => healthLabels.includes(h))) {
return false;
}
}
return true;
});
return filteredRecipes;
}
//Language code
let exceeded = "You have exceeded the MONTHLY quota for Characters on your current plan, BASIC. Upgrade your plan at https://rapidapi.com/googlecloud/api/google-translate1"
const defaultLocale = navigator.language.slice(0,2)
let locale
let translations = {}
document.addEventListener("DOMContentLoaded", () => {
setLocale(defaultLocale)
bindLocaleSwitcher(defaultLocale)
})
function translateElement(element){
const key = element.getAttribute("data-i18n-key")
const translation = translations[locale][key]
element.innerText = translation
}
async function setLocale(newLocale){
if(newLocale===locale) return
const newTranslations = await fetchTranslationsFor(newLocale)
locale = newLocale
translations = newTranslations
translatePage()
}
async function fetchTranslationsFor(newLocale){
const response = await fetch(`/lang/${newLocale}.json`)
return await response.json()
}
function translatePage(){
document.querySelectorAll("[data-i18n-key]").forEach(translateElement)
}
function translateElement(element){
const key = element.getAttribute("data-i18n-key")
const translation = translations[key]
element.innerText = translation
}
function bindLocaleSwitcher(initialValue){
const switcher = document.getElementById("languages").children
for(const sw of switcher){
sw.addEventListener('click', () => {
setLocale(sw.id)
input.value = ""
results.innerHTML = ""
})
}
}
这是我的CSS代码:
@import url('https://fonts.googleapis.com/css2?family=Grand+Hotel&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@500;700&display=swap');
.container{
background-color: #FDEEDC;
}
body{
margin: 0;
padding: 0;
background-color: #FDEEDC;
}
#languages{
display: flex;
justify-content: center;
margin-bottom: 15px;
}
#languages > div{
background-repeat: no-repeat;
background-position: center;
background-size: 180%;
border-radius: 999px;
width: 30px;
height: 30px;
margin-left: 2vh;
margin-top: 2vh;
transition: all .2s;
}
#languages > div:hover{
filter: brightness(105%);
background-size: 220%;
transition: all .2s;
}
#languages > div:active{
filter: brightness(85%);
}
#de{
background: url('svg/Flag_of_Germany.svg');
}
#en{
background: url('svg/gb.svg');
}
/* TEST ende */
#photo{
background-color: #FDEEDC;
height: 50vh;
}
#search{
position: absolute;
z-index: 1;
width: 100%;
height: 78px;
align-items: center;
justify-content: center;
display: flex;
top: 0;
margin-top: 57vh;
background-color: #FDEEDC;
}
#searchbar{
background-color: #FFC3A1;
width: 70%;
height: 80px;
align-items: center;
border-radius: 60px;
margin-right: 10px;
justify-content: center;
display: flex;
}
#button{
background-color: #FDEEDC;
}
#cards{
background-color: #FDEEDC;
margin-top: 100px;
}
#food{
height: 22%;
width:22% ;
align-items: center;
justify-content: center;
display: flex;
padding-top: 7px;
}
#logo{
align-items: center;
justify-content: center;
display: flex;
margin: auto;
}
#input{
width: 90%;
font-size: 28px;
border: 0;
background-color: #FFC3A100;
color: #FDEEDC;
}
#paw{
width: 9vh;
height: 9vh;
transform: scaleX(-1);
margin-left: 15px;
margin-right: 10px;
}
#input:focus{
outline: none;
}
p{
font-family: 'Grand Hotel', cursive;
font-size: 70px;
}
r{
font-family: 'Times New Roman';
font-size: 20px;
}
e{
font-family: 'Grand Hotel', cursive;
font-size: 30px;
}
#enter{
height: 8vh;
width: 8vh;
margin-left: 1vh;
background-color: #F0997D;
border-radius: 70px;
transition: 300ms;
}
#enter:hover{
cursor: pointer;
background-color: #F2B4B4;
background-size: 220%;
transition: all .2s;
}
.card{
border-radius: 10px;
border:10px solid #F2B4B4;
width:300px;
padding: 10px;
background-color: #FFDECF;
margin: 20px;
float: left;
height: 1000px;
}
.card-ing-top{
height: 300px;
width: 300px;
object-fit: cover;
border-radius: 10px;
}
.card-title{
font-family: Montserrat;
font-size: 20px;
}
.btn{
text-decoration: none;
font-family: Montserrat;
font-weight: 400;
color: #A75D5D;
}
在我的本地主机中,我检查了我的应用程序的功能。我在搜索栏中输入了一个像“burer”这样的词,并在健康过滤器中输入了“high-protein”,然后按下了搜索按钮。然而,搜索的过滤器功能不起作用,这意味着get不起作用,我没有根据我的搜索得到任何过滤后的食谱。
1条答案
按热度按时间zkure5ic1#
看起来你的API查询字符串不正确,返回了一个400错误。例如,如果你删除了最后一个参数(例如&calories=),那么响应是正确的。请查看文档。