fetch data from user input - javascript

So i want the user to input a date into #dateUsetInput, then after they click the button i want the fetch function to grab that input and use it to fetch the appropiate image from that date.
But when i do that this error appears:
VM113:1 Uncaught (in promise) SyntaxError: Unexpected end of JSON input
at getimages (index.js:16:29)
getimages # index.js:16
await in getimages (async)
(anonymous) # index.js:12
This is the javascript code:
/*
i want user to input a date
if the date isnt valid put message 'message not valid';
get the date and put it into the fetch function
after that put the image on the screen along with the name of the rover
*/
const button = document.getElementById('updatePic')
button.addEventListener('onclick', getimages())
async function getimages(){
const response = await fetch(`https://api.nasa.gov/mars-photos/api/v1/rovers/curiosity/photos?earth_date=${document.getElementById("dateUserInput").value}&api_key=rwX3pO8mONvdxngtstqSuNfwhrwMoGTy6clxqSnu`)
const data = await response.json()
}
and this is the html code:
<!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>Document</title>
<link href="styles.css" rel="stylesheet">
<script src="index.js" defer></script>
</head>
<body>
<input type="text" id="dateUserInput">
<button type="button" id="updatePic">Update Picture</button>
<div class="roverImage"></div>
</body>
</html>
What is wrong and what can i do?

You're calling the API with an empty input value when the page is first loaded, not when the user clicks on the button.
The first argument to addEventListener is an event name. onclick is not an event, it's an HTML attribute name that corresponds to the click event.
The second argument must be a function. You're calling the function, not passing a reference to the function.
const button = document.getElementById('updatePic')
button.addEventListener('click', getimages)
async function getimages() {
const response = await fetch(`https://api.nasa.gov/mars-photos/api/v1/rovers/curiosity/photos?earth_date=${document.getElementById("dateUserInput").value}&api_key=rwX3pO8mONvdxngtstqSuNfwhrwMoGTy6clxqSnu`)
const data = await response.json()
}

Related

data.indexOf is not a function error in [tabulator]

data.indexOf is not a function error in Tabulator JavaScript Library.
Complete error message:
[Error] TypeError: data.indexOf is not a function. (In 'data.indexOf("{")', 'data.indexOf' is undefined)
load (tabulator.js:6075)
_loadInitialData (tabulator.js:7971)
_create (tabulator.js:7841)
(anonieme functie) (tabulator.js:7756)
And warning:
Table Not Initialized - Calling the redraw function before the table is initialized may result in inconsistent behavior, Please wait for the `tableBuilt` event before calling this function
I used the setup as described in the doc, browser based so tabulator.js and tabulator.css in the location that is in the html. Nothing else done.
My HTML:
<!DOCTYPE html>
<html lang="nl">
<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/tabulator.css">
<!-- <link rel="stylesheet" href="css/tabulator.css.map"> -->
<link rel="stylesheet" href="css/layout.css">
<link rel="stylesheet" href="css/style.css">
<script defer src="js/tabulator.min.js"></script>
<script defer src="js/crud.js"></script>
<script defer src="js/data.js"></script>
<script defer src="js/assess.js"></script>
<title>DMMA</title>
</head>
<body>
<main id="home">
<h1 class="center-text dark-blue-text">Datamanagement Maturity Assessment</h1>
<div id="entree" class="container"></div>
<div class="output container"></div>
</main>
</body>
</html>
My javascript in assess.js:
document.addEventListener('DOMContentLoaded', async function() {
// the assObj is the data of assessment objects I want to retrieve
const assObj = new dataProvider;
// Use Tabulator
assObj.get('api.php/records/AssmntPlusObjects')
// .then(async dataArray => displayRecords(dta, false)) // Works!
.then(dataArray => {
let table = new Tabulator("#entree", {
data: dataArray,
autoColumns: true
})
})
.catch(err => displayError(err, null))
});
The assObj.get goes to a fetch class that gets the data from a MySQL database that gets the data via a PHP generic API. That all works.
The data array with objects is transformed to JavaScript object OK. The Tabulator gives the above error.
The site is on an internet provider host, I don't want to run another MySQL locally.
Any suggestions? Setup wrong?
dataArray is either empty or undefined. Check by console.log(dataArray)
Found the culprit! I needed get to the records in dataArray with
data: dataArray.records,
That's it!
I found that amazing because in a custom table function I built with the data (the displayRecords(dataArray, false)) it just worked without the .records property.
Thanks for putting me on the track of the contents of the dataArray.

Why does my button not fire the onclick function after i search for it with a querySelector

Basic 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>Document</title>
</head>
<body>
<button class = "hitknop">Hit!</button>
</body>
<script src="index.js" defer></script>
</html>
My JS
const deckinit = "https://deckofcardsapi.com/api/deck/new/shuffle/?deck_count=1";
const hitknoppie = document.querySelector("hitknop");
let deckId;
async function deckophalen(){
const response = await fetch (deckinit);
const deckopties = await response.json();
deckId = deckopties.deck_id;
console.log(deckId);
}
deckophalen();
hitknoppie.onclick = async function (){
const kaartlink = `https://deckofcardsapi.com/api/deck/${deckId}/draw/?count=1`;
const response = await fetch (kaartlink);
const kaart = await response.json();
console.log(kaart);
}
I was expecting it to show the result of a single card, but it now just gives me the error that I cannot set properties of null setting 'onclick'.
I tried moving the script tag and adding defer to my Js document without success.
You must add . because you are calling a class. It must look like this:const hitknoppie = document.querySelector(".hitknop");

How to get REST API JavaScript fetch object value to HTML?

How can I get printed console object value to HTML?
I have JavaScript fetch code like this:
const comments = fetch("https://api.github.com/repos/pieceofdiy/comments/issues/1")
.then((response) => response.json())
.then((labels) => {
return labels.comments;
});
const printComments = () => {
comments.then((number) => {
console.log(number);
});
};
printComments()
printComments() numeric object value shows correct in console, but how to show it in HTML
to <span id="comments">..</span> ?
With JS you can edit the DOM Hierarchy by searching for your desired Element to change.
const commentsEl = document.querySelector('.comments');
commentsEl.innerHTML = printComments();
With document.querySelector(CSS-Selector) you can search the DOM-Tree for a sufficient Element matching your Selector
We store the Element in a variable and change the Content of this Element by saving the comments in the property .innerHTML.
I've added a snippet demonstrating the changes below, and also changed some bits to improve your code.
As the fetch-Method is asynchronous, you’ll see fetching comments ... for a brief moment, as we change the content when the fetch finished and we got the results.
const commentsEl = document.querySelector('.comments');
// We fetch the comments as before
fetch("https://api.github.com/repos/pieceofdiy/comments/issues/1")
.then((response) => response.json())
.then((labels) => {
// But when we get the results, we immedietly change the contents of the comments span.
commentsEl.innerHTML = labels.comments;
});
<div class="container">
<p>Comments:</p>
<span class="comments">Fetching comments ...</span>
</div>
You could try setting a p tag with an id, ex: <p id=“comments”>and then using document.getElementById(“comments”).innerValue = number;
Place that second piece of code into printComments()
First you need to get your span tag in your html document.
Then define the innerHtml property of the span element by the value returned by the promise, in this case in your case the value is returned through a callback, so you simply have to perform the process in the scope of the callback.
Here is a snippet to illustrate this:
<!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>Document</title>
</head>
<body>
<span id="comments"></span>
<script>
const span = document.getElementById("comments");
const comments = fetch("https://api.github.com/repos/pieceofdiy/comments/issues/1")
.then((response) => response.json())
.then((labels) => {
return labels.comments;
});
comments
.then(res => span.innerHTML = res)
.catch(err => console.log(err));
</script>
</body>
</html>
But it can be done more cleanly this way:
<!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>Document</title>
</head>
<body>
<ol>
<li>Comments: <span id="comments1"></span></li>
<li>Comments: <span id="comments2"></span></li>
<li>Comments: <span id="comments3"></span></li>
</ol>
<script>
const comments1 = document.getElementById("comments1");
const comments2 = document.getElementById("comments2");
const comments3 = document.getElementById("comments3");
const printComment = async (url, HTMLTag) => {
try {
const request = await fetch(url);
const response = await request.json();
HTMLTag.innerHTML = response.comments;
} catch (error) {
console.log(error);
}
};
printComment("https://api.github.com/repos/pieceofdiy/comments/issues/1", comments1);
printComment("https://api.github.com/repos/pieceofdiy/comments/issues/1", comments2);
printComment("https://api.github.com/repos/pieceofdiy/comments/issues/1", comments3);
</script>
</body>
</html>
Good luck !

The getElementByID isnt showing the value

PLeaseHelp. it wont show the Value, even for form authentication, to get username & password values,I was trying the same methods.
<!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>Document</title>
</head>
<body>
<h1 id="result">Selected movie is </h1>
<select id="movie" onchange="showmovie()">
<option value="Spiderman">Spiderman</option>
<option value="Spiderman2">Spiderman2</option>
<option value="Spiderman3">Spiderman3</option>
</select>
</body>
</html>
<script>
var movie = document.getElementById("movie").value
function showmovie(){
alert("Changed")
document.getElementById("result").innerHTML="Movie chosen is"+movie
}
</script>
Try with this function showmovie
<script>
function showmovie() {
//Selected option
var selectedMovie = document.getElementById("movie").value;
document.getElementById("result").innerHTML = "Movie chosen is " + selectedMovie;
}
</script>
The issue here is because of the line var movie = document.getElementById("movie").value being executed just one time at the beginning (you could verify that adding console.log(movie); just after the movie variable declaration)
(movie stores then the value 'Spierdaman') and it never executes again with the calls for showmovie() function, so you could just move the movie declaration line above inside the function so it executes each time the action occurs and then having the good values.
Other details : To have a compliant code i suggest moving the script bloc to part just before and dont forget to add semicolons ';' at the end of each line ! + Better approach would be to use an eventListener as suggested by #T.J. Crowder in comments section above

Why did fetch() API failed to retrieve custom HIBP JSON data?

I am trying to use the Have I Been Pwned? API to retrieve a list of breaches for a given email account.
I retrieve this list using the fetch() API. In the browser it looks like there is a connection to the HIBP website but the expected breaches are not visible.
I think this is a JSON problem because the API returns results without a root tree (?) (e.g. [breaches:{"Name"... - only the {"Name"}), so I think I'm making a mistake at the iteration step in the JS file. Also, I'm not calling the 'retrieve' function in the HTML file correctly because the browser throws an error: 'Uncaught ReferenceError: retrieve is not defined', but this is a side-issue (fetch('https://haveibeenpwned.com/api/v2/breachedaccount/test#example.com') doesn't work either).
This is my first week working with JS, fetch(), and JSON, so I consulted a couple of sources before asking this question (but I still can't figure it out, after a couple of days):
How to Use the JavaScript Fetch API to Get Data
fetch API
API methods for HaveIBeenPwnd.com (unofficial)
Where is the actual problem?
The index.html file:
<!DOCTYPE html>
<html lang=en>
<head>
<title>test</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="robots" content="noindex, nofollow">
</head>
<body id="top">
<header id="header">
<div class="content">
<h1 style="text-align: center">Put an email in this box</h1>
<input type="email" id="InputBox" value="" autocapitalize="off" spellcheck="false" />
<button type="submit" id="PwnedButton" onclick="retrieve">pwned?</button>
<ul id="results"></ul>
</div>
</header>
<script src="test.js"></script>
</body>
</html>
The test.js file (I know that JS is an interpreted language - so empty characters affect execution speed - but I made it more readable for this example):
function createNode(element) {
return document.createElement(element); // Create the type of element you pass in the parameters
}
function append(parent, el) {
return parent.appendChild(el); // Append the second parameter(element) to the first one
}
const account = document.getElementById('InputBox');
const PwnedButton = document.getElementById('PwnedButton');
const results = document.getElementById('results');
fetch('https://haveibeenpwned.com/api/v2/breachedaccount/' + account)
.then((resp) => resp.json()) // Transform the data into json
.then(function(retrieve) {
let breaches = retrieve.Name; // Get the results
return breaches.map(function(check) { // Map through the results and for each one run the code below
let span = createNode('span'); // Create the element we need (breach title)
span.innerHTML = `${breaches}`;
append(results, span);
})
})
.catch(function(error) {
console.log(JSON.stringify(error));
});
let breaches = retrieve.Name;
retrieve is not an object with a Name property.
It is an array containing multiple objects, each of which has a Name property.
You have to loop over it.
e.g.
retrieve.forEach( item => {
let breaches = retrieve.Name;
console.log(breaches);
});
breaches.map
… and the Name is a string, so you can't map it. You can only map an array (like the one you have in retrieve).
I have created working version of what are you possible going to implement, taking Name field from result. https://jsfiddle.net/vhnzm1fu/1/ Please notice:
return retrieve.forEach(function(check) {
let span = createNode('span');
span.innerHTML = `${check.Name}<br/>`;
append(results, span);
})

Categories

Resources