So I am struggling with APIs and how to handle them. I am currently stuck on an error and haven't been able to figure out how to fix it. My goal with this project is to be able to use the cocktailapi and have a search bar where a user can search by an ingredient, ie gin. I get the below error when I run the code. I'm just not sure how to fix this.
Uncaught (in promise) SyntaxError: Unexpected end of JSON input
at extrafile.js:25:34
I also get the below error why I type input in the search bar.
Uncaught TypeError: Cannot set properties of null (setting 'innerHTML')extrafile.js:45
at displayIngredientResults (extrafile.js:45:26)
at HTMLInputElement. (extrafile.js:18:5)
Any advice is greatly appreciated.
window.addEventListener('DOMContentLoaded', (event) => {
console.log('DOM fully loaded and parsed');
});
const drinks = document.getElementById('drinks1');
const searchBar = document.getElementById('search-Bar');
let ingredientResults = [];
searchBar.addEventListener('keyup', (e) => {
const searchString = e.target.value.toLowerCase();
const filteredIngredients= ingredientResults.filter((drinks) => {
return (
drinks.strIngredient.toLowerCase().includes(searchString)
);
});
displayIngredientResults(filteredIngredients);
});
const loadIngredientResults = () => {
try {
const res = fetch('https://www.thecocktaildb.com/api/json/v1/1/filter.php?i='+ searchBar.value)
.then(res => {return res.json()});
// ingredientResults = res.JSON().results;
// displayIngredientResults(ingredientResults);
} catch (err) {
console.error(err);
}
};
const displayIngredientResults = (results) => {
const htmlString = results
.map((drinks) => {
return `
<div class="card">
<div class="card-body">
<h2>${drinks.strIngredient}</h2>
</div>
</div>
`;
})
.join('');
drinks.innerHTML = htmlString;
};
loadIngredientResults();
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<link rel="stylesheet" href="styles.css" />
<script src="searchbyingredient.js"></script>
</head>
<body>
<div class="container">
<h1>✨Cocktails ✨</h1>
<div id="searchWrapper">
<input
type="text"
name="searchBar"
id="searchBar"
placeholder="Search for a Cocktail"
/>
</div>
<ul id="cocktailsList"></ul>
</div>
<!DOCTYPE html>
<html lang="en">
<head>
<title>Cocktail App</title>
<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>Document</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-0evHe/X+R7YkIZDRvuzKMRqM+OrBnVFBL6DOitfPri4tjfHxaWutUpFmBp4vmVor" crossorigin="anonymous">
<link rel="stylesheet" href="styles.css">
</head>
<br>
<div class="card" style="width: 18rem;">
<div class="card-body" id = " card">
<label for="site-search" ></label>
<body>
<div class="container2">
<div id="searchWrapper">
<input
type="text"
name="search-Bar"
id="search-Bar"
placeholder="Enter Main Ingredient"
/>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.2.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-pprn3073KE6tl6bjs2QrFaJGz5/SUsLqktiwsUTF55Jfv3qYSDhgCecCxMW52nD2" crossorigin="anonymous"></script>
<script src="extrafile.js"></script>
<!-- <script src="searchbyingredient.js"></script> -->
</body>
</html>
A couple issues here:
The following line sets drinks as null or undefined, since your HTML does not already contain a div with the id of "drinks1".
const drinks = document.getElementById('drinks1');
If you want to create the element in Javascript, you'll need to use a library like jQuery to help you do that like this https://api.jquery.com/add/, or use vanilla javascript like this https://www.javascripttutorial.net/dom/manipulating/create-a-dom-element/
Also, you never set the value of ingredientResults so it is always [], also the function loadIngredientResults returns a promise, and you cannot depend on ingredientResults to not be [] when you execute the following line:
const filteredIngredients= ingredientResults.filter((drinks) => {
return (
drinks.strIngredient.toLowerCase().includes(searchString)
);
});
Consider creating an async/await asynchronous call on keyup and ensuring that the API call has succeeded or that filteredIngredients has a value.
Related
Can you please tell me how to transfer the data received from Json to a variable for output to the site?
I receive the data and output it to the page (for clarity), then it is necessary to transfer it to a variable for processing and output.
Next, the "showData()" function displays the received data on the site.
Thank you in advance!
let testBox = document.querySelector('.goods .container');
// get data
function getData() {
fetch('https://jsonplaceholder.typicode.com/posts')
.then(response => response.text())
.then(text => testBox.innerHTML = text)
};
// show data
let allGoods = getData(); // how to pass data to a variable?
function showData() {
let outGoods = '';
for (let key in allGoods) {
outGoods += `
<div class="goods__item">
<a><img src="${allGoods[key].image}"/></a>
<div class="goods__tx">
<h2>${allGoods[key].name}</h2>
<p>${allGoods[key].desc}</p>
<span>${allGoods[key].availability}</span>
<div class="goods__bottom">
<b>${allGoods[key].price} $</b>
<div class="goods__btn">
<button class="goods__minus" data-id="${key}">-</button>
<button class="goods__plus" data-id="${key}">+</button>
</div>
</div>
</div>
</div>`
}
let goodsContent = document.querySelector('.goods .container');
goodsContent.innerHTML = outGoods;
}
showData();
<!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">
<link rel="icon" href="img/js.png" sizes="64x64">
<link rel="stylesheet" href="css/style.css">
<title>Document</title>
</head>
<body>
<section class="goods">
<div class="container"></div>
</section>
<section class="cart">
<div class="container"></div>
</section>
<script src="db.json"></script>
<script src="script.js"></script>
</body>
</html>
I'm building a Website on which you can enter your Minecraft UUID and it gives you a 3D Render of your Minecraft Skin. Unfortunately the API I am using only supports UUIDs. I thought the website could work like this:
You Enter a Username
The Username gets converted to a UUID using some API
The UUID gets send to the other API which hands you a Render of your Skin
How can this be done?
<!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">
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" media="screen" href="https://fontlibrary.org//face/minecraftia" type="text/css"/>
<title>Check Minecraft Skin!</title>
<script src="https://kit.fontawesome.com/c0ac5a1789.js" crossorigin="anonymous"></script>
</head>
<body>
<main>
<input type="text" id="skinname" placeholder="Enter your UUID" />
<button class="button">Search</button>
<div class="output">
<img id="image"/>
</div>
<script>
const skinname = document.getElementById("skinname");
const button = document.querySelector("button");
const image = document.getElementById("image");
button.addEventListener("click", async () => {
const rta = await fetch(
"https://visage.surgeplay.com/full/500/" + skinname.value
);
image.src = rta.url;
});
</script>
</main>
</body>
</html>
You can use official Mojang API
https://api.mojang.com/users/profiles/minecraft/<username>
I'm working on an app that makes fetch calls to a dictionary API based on the user's input. The problem is, I can't seem to get the input value from the search bar. Currently, all that's being logged to the console is an empty string. I currently have my code inside of a DOMContentLoaded event listener. When I take my code out of the DOMContentLoaded function, I am getting a null value returned. This is incredibly straightforward but I can't seem to figure out what is getting muddled here. Here is the code;
window.addEventListener('DOMContentLoaded', () => {
const searchBar = document.getElementById('search-bar');
const userInput = searchBar.value;
const searchButton = document.getElementById('search-button');
const test = () => console.log(userInput);
searchButton.addEventListener('click', test);
});
<!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">
<script src="app.js"></script>
<title>Dictionary</title>
</head>
<body>
<h1>Dictionary</h1>
<input type="text" id="search-bar" placeholder="Find a definition"/>
<button id="search-button">Search</button>
<div id="results-area">
</div>
</body>
</html>
Thanks for the help.
The issue was you're getting always the first value of input which is empty, to get the new value call searchBar.value on the click of button.
window.addEventListener('DOMContentLoaded', () => {
const searchBar = document.getElementById('search-bar');
const searchButton = document.getElementById('search-button');
const getInputValue = () => {
let userInput = searchBar.value;
console.log(userInput);
}
searchButton.addEventListener('click', getInputValue);
});
<!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">
<script src="app.js"></script>
<title>Dictionary</title>
</head>
<body>
<h1>Dictionary</h1>
<input type="text" id="search-bar" placeholder="Find a definition" />
<button id="search-button">Search</button>
<div id="results-area">
</div>
</body>
</html>
So I have this issue, I want to use vanilla JavaScript because I don't like how bloated JQuery is. Now, the problem I have is when I load my file into the div withe the following code:
async function loadPage (pagename) {
await fetch(pagename, {
headers: {
"Content-Type": "text/html; charset=utf-8"
}
})
.then((response) => response.text())
.then((html) => {
document.getElementById("Loader").innerHTML = html;
})
.catch((error) => {
console.warn(error);
});
}
my JavaScript in the page doesn't fire.
I have tried running JavaScript in the file and also with external files.
When I put the JavaScript file for this HTML in the main page it fires, but it is littered with errors. When I use the JQuery load function it works fine though, is there any way to get this right in vanilla JavaScript or am I gonna have to use JQuery??
HTML for details.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">
<link rel="stylesheet" href="css/autocomplete.css">
<link rel="stylesheet" href="css/details.css">
<link rel="stylesheet" href="css/tablestyles.css">
<title>Search</title>
</head>
<body>
<!-- Enter search criteria here -->
<div id="top">
<button onclick="search();">Search</button>
<div class="autocomplete" style="width:300px;">
<input type="text" name="searchPhrase" id="searchPhrase" placeholder="Search Phrase" autocomplete="off">
</div>
<!-- Options for autocomplete -->
<div id="displaydiv">
</div>
</div>
<div id="results">
</div>
</body>
<script src="js/autocomplete_input.js"></script>
<script src="js/tablecreator.js"></script>
<script src="js/details.js"></script>
</html>
loadPage is called by main.js
function openSearch(){
loadPage('details.html');
}
I tried replicating it in codesandbox!
I'm learning, and It's been few days I've been stuck on this weather app project.
Since i'm new to APIs everything seems so complicated, I'm unable to get response properly from API And this time error I'm getting is "Uncaught (in promise) SyntaxError: Unexpected end of JSON input"
My code for reference:
// navigator.geolocation.getCurrentPosition(pos=>{console.log(pos)});
async function getLoc(){
const apikeyloc = "//apikey//";
const locationapi = "http://dataservice.accuweather.com/locations/v1/cities/autocomplete"
let query = document.getElementById("location").value;
const inputbox = document.getElementById("location");
let locationList;
inputbox.addEventListener('keydown',async function(){
const api = fetch(`${locationapi}${apikeyloc}${query}`);
(await api).json().then(res=>{
console.log(res);
res.forEach(item => {
if (item.LocalizedName.indexOf(inputbox.value != -1)) {
locationList = `${item.LocalizedName},${item.AdministrativeArea.LocalizedName},${item.CountryLocalizedName}`;
console.log(locationList)
}
});
})
}
)
}
getLoc()
<!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>Weather app</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div class="container">
<Nav>
<div class="timezone">
<div class="city">CityName</div>
<div class="icon">icon</div>
</div>
<div class="search">
<input type="text" id="location" placeholder="Type Location...">
</div>
</Nav>
<div class="weather">
<div class="temprature">28deg</div>
<div class="wdesc">Today is Sunny</div>
</div>
</div>
<script src="js/script.js"></script>
</body>
</html>
Any help would be appreciated.
You only assign the query variable once, to the document.elementById "location". This is empty at the loading of the page, so every api call you make in the keydown event will be with an empty query, resulting in a blank (non-json) response from the api.
Assign the query variable inside the key event. Also use keyup instead of keydown so that accessing the element's has the correct value. An ajax call on keyup should also be delayed, but take it one step at a time.
// navigator.geolocation.getCurrentPosition(pos=>{console.log(pos)});
async function getLoc(){
const apikeyloc = "?apikey=Om2MRV8SFRjSuVtjnisRhKGxTNQRzhrL&q=";
const locationapi = "http://dataservice.accuweather.com/locations/v1/cities/autocomplete"
const inputbox = document.getElementById("location");
let locationList;
inputbox.addEventListener('keyup',async function(){
//assign it here.
var query = document.getElementById("location").value;
const api = fetch(`${locationapi}${apikeyloc}${query}`);
(await api).json().then(res=>{
console.log(res);
res.forEach(item => {
if (item.LocalizedName.indexOf(inputbox.value != -1)) {
locationList = `${item.LocalizedName},${item.AdministrativeArea.LocalizedName},${item.CountryLocalizedName}`;
console.log(locationList)
}
});
})
}
)
}
getLoc()
<!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>Weather app</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div class="container">
<Nav>
<div class="timezone">
<div class="city">CityName</div>
<div class="icon">icon</div>
</div>
<div class="search">
<input type="text" id="location" placeholder="Type Location...">
</div>
</Nav>
<div class="weather">
<div class="temprature">28deg</div>
<div class="wdesc">Today is Sunny</div>
</div>
</div>
<script src="js/script.js"></script>
</body>
</html>