Unable to get response from api and convert it to Json - javascript

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>

Related

How to get the data received from Json to a variable for output to the site?

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>

Turn Minecraft name to UUID in javascript

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>

Textfield Input Value Returning Null

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>

implementing search bar in api

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.

I'm trying to create a function that adds my values from an input field to an array using the push method. Showing - cannot read properties of null

Some thing is wrong. It is showing cannot read properties of null (addEventListener) on the console. please help. I have created an input field and a button. I am trying to get the value from the input field and going to put them in an array taskStorage.
'use strict'
let taskStorage = [];
// input declarations
const field = document.getElementById('addTodoString1').value;
const addTaskBtn = document.getElementById('addMoreBtn');
addTaskBtn.addEventListener('click', ()=> {
taskStorage.push(field.value);
console.log(taskStorage);
})
<!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>Palmdale To Do</title>
<link rel="stylesheet" href="style/landscape.css">
</head>
<!-- create a to do list -->
<!-- create an empty array -->
<!-- push items to an array using shift -->
<body>
<section id='main'>
<section class="header">
<h3>To Do List</h3>
</section>
<section class="inputFieldSection">
<div class="inputsFieldBox">
<input type="text" id='addTodoString1' placeholder="list your to do here">
</div>
<div class="btnBox">
<button class="addMoreBtn">
Add
</button>
</div>
</section>
</section>
<section id="result">
<h3>results will display here.
</h3>
</section>
<script src="script.js"></script>
</body>
</html>
You need to provide "id attribute" to button instead of class.
and you need to change const field = document.getElementById('addTodoString1').value; to const field = document.getElementById('addTodoString1');
let taskStorage = [];
// input declarations
const field = document.getElementById('addTodoString1');
const addTaskBtn = document.getElementById('addMoreBtn');
addTaskBtn.addEventListener('click', ()=> {
taskStorage.push(field.value);
console.log(taskStorage);
})
<!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>Palmdale To Do</title>
<link rel="stylesheet" href="style/landscape.css">
</head>
<!-- create a to do list -->
<!-- create an empty array -->
<!-- push items to an array using shift -->
<body>
<section id='main'>
<section class="header">
<h3>To Do List</h3>
</section>
<section class="inputFieldSection">
<div class="inputsFieldBox">
<input type="text" id='addTodoString1' placeholder="list your to do here">
</div>
<div class="btnBox">
<button id="addMoreBtn">
Add
</button>
</div>
</section>
</section>
<section id="result">
<h3>results will display here.
</h3>
</section>
<script src="script.js"></script>
</body>
</html>
That is because addTaskBtn is null, and it's null because there is not element in you code with the id "addMoreBtn".
Either replace class="addMoreBtn" with id="addMoreBtn" or use document.querySelector('.addMoreBtn') to get the element as a class
Also remove .value from this line:
const field = document.getElementById('addTodoString1').value;
'use strict'
let taskStorage = [];
// input declarations
const field = document.getElementById('addTodoString1');
const addTaskBtn = document.querySelector('.addMoreBtn');
addTaskBtn.addEventListener('click', ()=> {
taskStorage.push(field.value);
console.log(taskStorage);
})
<!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>Palmdale To Do</title>
<link rel="stylesheet" href="style/landscape.css">
</head>
<!-- create a to do list -->
<!-- create an empty array -->
<!-- push items to an array using shift -->
<body>
<section id='main'>
<section class="header">
<h3>To Do List</h3>
</section>
<section class="inputFieldSection">
<div class="inputsFieldBox">
<input type="text" id='addTodoString1' placeholder="list your to do here">
</div>
<div class="btnBox">
<button class="addMoreBtn">
Add
</button>
</div>
</section>
</section>
<section id="result">
<h3>results will display here.
</h3>
</section>
<script src="script.js"></script>
</body>
</html>

Categories

Resources