Javascript - looping through data with each click - javascript

I'm fairly new to Javascript I have been playing with some data fetching for the past few days. I created this very simple program (if you can even call it that), where if you click a button, it will generate a div with a random user (using jsonplaceholder API). My issue is, that whenever the button is clicked, it gives me all 10 users at once. I'd like it to give me one user with each click instead. As I said, I am fairly new to JS so I'm not sure how to aproach this (I guess some sort of a loop would be involved?). Any sort of advice, tips or anything would be welcomed ! Thank you !
Here is my code (Using Bootstrap 4 for styling and Axios for data fetching):
const mainButton = document.getElementById('mainButton');
const targetDiv = document.getElementById("targetDiv");
mainButton.addEventListener('click', () => {
axios
.get("https://jsonplaceholder.typicode.com/users")
.then(function(response) {
let ourRequest = response;
renderData(ourRequest.data);
})
.catch(function(error) {
console.log(error);
});
function renderData(data) {
var stringHTML = "";
for (i = 0; i < data.length; i++) {
stringHTML += `
<div class="col-md-4">
<div class="card">
<div class="card-header">
User ID: #${data[i].id}
</div>
<div class="card-body">
<h4 class="card-title">${data[i].name}</h4>
<p class="card-text">Email - <em>${data[i].email}</em></p>
<p class="card-text">Phone - <em>${data[i].phone}</em></p>
<p class="card-text">Address - <em>${data[i].address.street}, ${data[i].address.city}, ${data[i].address.zipcode}</em></p>
</div>
</div>
</div>
`;
}
targetDiv.insertAdjacentHTML("beforeend", stringHTML);
}
});
<!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">
<link rel="stylesheet" href="main.css">
<title>JSON Users</title>
</head>
<body>
<div class="container">
<div class="text-center my-5">
<h1 class="display-4">Random JSON Users</h1>
<p>This is a random user generator, click the below button to get a
random person!</p>
<button id="mainButton" class="btn btn-primary">Get User!</button>
</div>
<!-- Users -->
<div id="targetDiv" class="row">
</div>
</div>
<!-- JavaScript -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="main.js"></script>
</body>
</html>

If I get it right that your GET method is asking for users, so response contains more that one user. This response you send to renderData method and there you generate your div for each user from response. I supouse to change your GET method to get only one user or send only one user to renderData method like ourRequest.data[0] from your current solution.

Related

Conditionally rendering HTML elements with querySelector based on boolean value

I'm working on a Chrome extension so my approach is different to how I'd usually go about this.
I have the below HTML, which includes elements that may or may not be displayed depending on a boolean value in the javascript file:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" href="https://unpkg.com/mvp.css">
<link rel="stylesheet" href="popup.css">
</head>
<body class="container">
<header>
<h1 style="width: 400px">Title</h1>
<p style="font-size: 1rem;">Messages to non paying users</p>
<button class="join-btn">Join now!</button>
<a style="cursor: pointer; margin-top: 4px;">Message for paying users</a>
</header>
<script src="ExtPay.js"></script>
<script defer src="popup.js"></script>
</body>
</html>
The JS file is like so:
const extpay = ExtPay('my-ext-ID');
document
.querySelector('button')
.addEventListener('click', extpay.openPaymentPage);
document.querySelector('a').addEventListener('click', extpay.openPaymentPage);
extpay
.getUser()
.then((user) => {
if (user.paid) {
document.querySelector('p').innerHTML = 'Message to paying users';
document.querySelector('button').remove();
} else {
document.querySelector('a').remove();
}
})
.catch((err) => {
document.querySelector('p').innerHTML =
"Error fetching data :( Check that your ExtensionPay id is correct and you're connected to the internet";
});
So what this does is that if the user is a paying customer, then the contents of the <p> changes and the "Join now" button is removed, and if they are not a paying customer, the <a> is removed.
The problem I have with this approach is that for a short amount of time (<1sec) - the the HTML renders in its entirity (including both elements for paying & non-paying users) before the JS kicks in and updates accordingly. How can I update this so that this doesn't happen? I have tried adding defer to the script calls but to no avail.
You can try another approach, You can create empty div with id and then based on the conditions you can create those p and button elements and append it to that div. Like for example:
<header>
<h1 style="width: 400px">Title</h1>
<div id="header"></div>
<a style="cursor: pointer; margin-top: 4px;">Message for paying users</a>
</header>
<script>
const para = document.createElement("p");
const node = document.createTextNode("This is new.");
para.appendChild(node);
//append it to (document.getElementById('header'))
if (!user.paid) {
var a = document.createElement("button");
a.innerText = "Join now!";
//append it to (document.getElementById('header'))
}
</script>

What could be wrong with my keypress event?

I'm trying to make a weather app, and use the API from openweathermap, I copied the baseurl from the web like this but it's not currently working...
const api = {
key:"03173bc8739f7fca249ae8d681b68955"
baseurl:"https://home.openweathermap.org/api_keys"
}
const searchbox=document.querySelector('.search-box');
searchbox.addEventListener('keypress', setQuery)
function setQuery(evt){
if (evt.keyCode==13)
//getResults(searchbox.value)
console.log(searchbox.value)
}
So when I type in the search box, the console doesn't show anything...
This is my html file:
<!DOCTYPE html>
<html>
<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> </title>
<link rel="stylesheet" href="weather.css">
</head>
<body>
<div class="app-wrap">
<header>
<input type="text" autocomplete="off" class="search-box" placeholder="Search for a city...">
</header>
<main>
<section class="location">
<div class="city">HCM City, Viet Nam</div>
<div class="date">Friday 25 June 2021</div>
</section>
<div class="current">
<div class="tempt">15<span>°C</span></div>
<div class="weather">Sunny</div>
<div class="high-low">13°C / 16°C</div>
</div>
</main>
</div>
<script src="weather.js"></script>
</body>
</html>
Is there something wrong with the baseurl or something, can anybody tell me?
wrap the selector with " ";
const searchbox = document.querySelector(".search-box");
also correct your api obj:
const api = {
key: "03173bc8739f7fca249ae8d681b68955",
baseurl: "https://home.openweathermap.org/api_keys"
}
You missed to add single quote in querySelector.
const searchbox=document.querySelector('.search-box'); // Corrected
also you need to update the API object
const api = {
key:"03173bc8739f7fca249ae8d681b68955",
baseurl:"https://home.openweathermap.org/api_keys"
}

Fetching data from an API - Console Repeats

I am having a bit of trouble.
I need to create a website that will display three random Chuck Norris jokes using the following API: http://www.icndb.com/api/. I have to use the following URL to fetch the jokes: http://api.icndb.com/jokes/random/3.
My HTML is as follows:
<!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>Chuck Norris Jokes</title>
<link rel="stylesheet" href="css/main.css" type="text/css">
</head>
<body>
<!-- Added a navigation bar to display logo. -->
<nav class="navigation-bar">
<img src="images/Logo.png" alt=Logo id="logo" />
</nav>
<!-- Created a container so I can set the grid sections. -->
<div id="container">
<!-- First container for the heading and the image. -->
<div>
<h1>Chuck Norris Jokes</h1>
<img src="images/chuck.png" alt="Chuck Norris Armed" id="chuckshoot">
</div>
<!-- Second section for the text and for the button. -->
<div id="jokegen">
<div id="jokeTxt">
<p id="j1"></p>
<p id="j2"></p>
<p id="j3"></p>
</div>
<button id="jokeBtn" value="fetch">Click Here For A Chuckle!</button>
</div>
</div>
<script type="text/javascript" src="js/main.js"></script>
</body>
</html>
My Javascript is as follows:
// Created an array for the Chuck Norris jokes.
let joke = [];
// Attached an event handler to the button.
document.getElementById('jokeBtn').addEventListener('click', function () {
// Fetching the API.
fetch("http://api.icndb.com/jokes/random/3")
// Grabbing the information from the JSON file.
.then(res => res.json())
// Fetching the joke from value in JSON.
.then(function (result) {
for (let i = 0; i < result.value.length; i++) {
jokes = result.value[0].joke;
jokes2 = result.value[1].joke;
jokes3 = result.value[2].joke;
console.log(jokes);
console.log(jokes2);
console.log(jokes3);
console.log(typeof joke);
// Displaying the fetched jokes in HTML.
document.getElementById("j1").innerHTML = jokes;
document.getElementById("j2").innerHTML = jokes2;
document.getElementById("j3").innerHTML = jokes3;
}
}),
// If the above could not be executed and an error should occur.
error => {
console.log(error + "");
};
})
The HTML is showing correctly but in console all three jokes appear even if I call a single joke. Please see the screenshot below:
Thank you in advance for the help.
You can simplify the Javascript a little and use a forEach loop on the value property within the response.
The error => {console.log(error + "")} piece is not quite right - that should be within a catch segment - ie .catch( err=>console.log(err) ) or similar
document.getElementById( 'jokeBtn' ).addEventListener('click', ()=>{
fetch( 'https://api.icndb.com/jokes/random/3' )
.then( res => res.json() )
.then( json => {
if( json.type=='success' ){
json.value.forEach( ( obj, i )=>{
let node=document.getElementById( 'j' + ( i + 1 ) );
if( node )node.innerHTML=obj.joke;
})
}
})
})
<nav class="navigation-bar">
<img src="images/Logo.png" alt=Logo id="logo" />
</nav>
<div id="container">
<div>
<h1>Chuck Norris Jokes</h1>
<img src="images/chuck.png" alt="Chuck Norris Armed" id="chuckshoot">
</div>
<div id="jokegen">
<div id="jokeTxt">
<p id="j1"></p>
<p id="j2"></p>
<p id="j3"></p>
</div>
<button id="jokeBtn" value="fetch">Click Here For A Chuckle!</button>
</div>
</div>

I want to delete all checked lists pressing the delete button but I don't know how

I'm learning Javascript and now I'm making to-do list.I've finished the basic one but I want to add the delete button which delete all the checked lists to my to-do list.
I've tried some ways that I came up with and they all failed and I cannot find the answer by googling.
How can I do this ? If there is someone who know, please teach me . I'd appreciated if you could show me how.
this is my code ↓ the error happened saying cannot read property 'parentElement' of null at Object.deleteAll
deleteAll: function() {
let taskListItem, checkBox, checkBoxParent;
for (i=0; i<this.taskListChildren.length; i++){
taskListItem = this.taskListChildren[i];
checkBox = taskListItem.querySelector('input[type = "checkbox"]:checked');
checkBoxParent = checkBox.parentElement;
checkBoxParent.remove();
}
document.getElementById('deleteChecked').addEventListener('click', () => {
tasker.deleteAll();
});
🙏
// this is my HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>To Do List</title>
<link rel="stylesheet" href="css/styles.css">
<link href="https://use.fontawesome.com/releases/v5.6.1/css/all.css" rel="stylesheet">
</head>
<body onLoad = "tasker.construct();">
<div class="tasker" id="tasker">
<div class="error" id="error">Please enter a task</div>
<div class="tasker-header" id="tasker-header">
<input type="text" id="input-task" placeholder ="Enter a task">
<button id="add-task-btn"><i class="fas fa-plus"></i></button>
</div>
<div class="tasker-body">
<ul id="tasks">
</ul>
</div>
<button id="deleteChecked">Delete</button>
</div>
<script src="js/main.js"></script>
</body>
</html>
You can use the jQuery library and solve it as follows.
Step 1) Define in your html button element:
<button id="button" onclick="reset()"> RESET </button>
Step 2) define the 'reset ()' function, like this
function reset()
{
$("input:chceckbox").removeAttr("chcecked");
}
Good luck!!

text input in html to check for keywords using javascript and return a score

I have the following html page that seeks to check for keywords in text input and return a score depending on how many keywords are entered. For instance, if two keywords are returned, the score would be 2, and if the answer contains no keywords, then a score of 0 would be returned.
In the example below two accepted keywords have been used (e.g. good and eternal) and therefore the user would receive a score of 2.
I've made an attempt (a beginner to JS) but would appreciate some help.
UPDATE: The javascript i have used nearly works (to search for multiple keywords) but doesnt display the showscore variable correctly each time.
This is what I have so far:
<script>
document.getElementById('longanswer').addEventListener('input', function(e){
let keyword = e.target.value;
document.getElementById('greeting').innerHTML = "Just write this";
});
function displayScore() {
var showscore = 0;
var answer = document.getElementById('longanswer').value;
var keyword1="eternal";
var keyword2="good";
var keyword3="true";
if (answer.indexOf(keyword1)!=-1){
showscore=showscore+1
document.getElementById("displayscore").innerHTML = showscore;
} else if (answer.indexOf(keyword1)!=-1 & answer.indexOf(keyword2)!=-1){
showscore=showscore+2
} else if (answer.indexOf(keyword1)!=-1 & answer.indexOf(keyword2)!=-1 & answer.indexOf(keyword3)!=-1){
showscore=showscore+3
} else {
showscore=0
}
document.getElementById("displayscore").innerHTML = showscore;
}
</script>
The interface is below:
Whole code that can be easily re-created below:
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<title>Long Answer Question & Answers</title>
</head>
<body>
<form>
<h1> Q and A </h1>
<div class="form-group">
<label for="longanswer">What is the meaning of life?:</label><br>
<textarea rows="4" cols="100" id="longanswer">
</textarea>
<br>
<button onclick="displayScore()" type="button" class="btn btn-success">Submit</button>
</div>
</form>
<div class="card border-primary mb-3" style="max-width: 18rem;">
<div class="card-header">Score</div>
<div class="card-body text-primary">
<h5 class="card-title">Generating a score for your answer</h5>
<p class="card-text" id="displayscore">Once you've clicked submit we will display your score for this answer here.</p>
</div>
</div>
<script>
document.getElementById('longanswer').addEventListener('input', function(e){
let keyword = e.target.value;
document.getElementById('greeting').innerHTML = "Just write this";
});
function displayScore() {
var showscore;
var answer = document.getElementById('longanswer').value;
var keyword1="eternal";
var keyword2="good";
if (answer.indexOf(keyword1)!=-1)
{
showscore="found"
}
document.getElementById("displayscore").innerHTML = showscore;
}
</script>
To have it more dynamic, I'd use a new RegExp in which you can check the text; the length of match' result will be the score
let keywords = new RegExp("(" + ["foo", "bar", "baz"].join('|') + ")", 'gi');
document.getElementById('btn').addEventListener('click', e => {
document.getElementById('score').innerHTML =
document.getElementById('foo').value.match(keywords).length;
});
<textarea id="foo"></textarea>
<button id="btn">
Check
</button>
<div id="score">
</div>

Categories

Resources