When i try to run my index.html file
<div class="quote-text">
<i class="fas fa-quote-left"></i>
<span id="quote"></span>
</div>
<!-- author element -->
<div class="quote-author">
<span id="author"></span>
</div>
my textContent method is not showing anything.
const quoteText = document.getElementById("quote");
const authorText = document.getElementById("author");
let apiQuotes = []
function newQuote(){
const ranQuote = apiQuotes[Math.floor(Math.random() * apiQuotes.length)];
console.log(ranQuote);
console.log(ranQuote.text);
console.log(ranQuote.author);
console.log(quoteText);<!-- this shows null -->
console.log(authorText); <!-- this shows null -->
quoteText.textContent = ranQuote.text;
authorText.textContent = ranQuote.author;
};
async function getQuotes(){
const apiUrl = 'https://type.fit/api/quotes';
try{
const response = await fetch(apiUrl);
apiQuotes = await response.json()
newQuote();
}
catch(error){
}
}
getQuotes();
I console logged span element value and its logging null. And i can't change my desired value in span element
this is console screeenshot
Your code is working as expected, as you can see in the snippet below.
Make sure you are running this script after DOM elements are created.
Put your script just before </body>, or make sure it executes after DOMContentLoaded (Stack snippet below does this ^)
const quoteText = document.getElementById("quote");
const authorText = document.getElementById("author");
let apiQuotes = []
function newQuote() {
const ranQuote = apiQuotes[Math.floor(Math.random() * apiQuotes.length)];
console.log(ranQuote);
console.log(ranQuote.text);
console.log(ranQuote.author);
console.log(quoteText); <!-- this shows null -->
console.log(authorText); <!-- this shows null -->
quoteText.textContent = ranQuote.text;
authorText.textContent = ranQuote.author;
};
async function getQuotes() {
const apiUrl = 'https://type.fit/api/quotes';
try {
const response = await fetch(apiUrl);
apiQuotes = await response.json()
newQuote();
} catch (error) {}
}
getQuotes();
<div class="quote-text">
<i class="fas fa-quote-left"></i>
<span id="quote">Wait for the request to finish...</span>
</div>
<!-- author element -->
<div class="quote-author">
<span id="author"></span>
</div>
Related
I am trying to enable a sound feature on my dictionary API but am having problems with my code since its not working
const url = "https://api.dictionaryapi.dev/api/v2/entries/en/";
const result = document.getElementById("result");
const sound = document.getElementById("sound");
const btn = document.getElementById("search-btn");
btn.addEventListener("click", () => {
let inpWord = document.getElementById("inp-word").value;
fetch(`${url}${inpWord}`)
.then((response) => response.json())
.then((data) => {
console.log(data);
result.innerHTML = `
<div class="word">
<h3>${inpWord}</h3>
<button onclick="playSound()">
<i class="fas fa-volume-up"></i>
</button>
</div>
i was trying to make a streaming website using Agora.io
in my JavaScript, i made a player template which will add to my webpage every time a new user enters. the client.on method should detect a new user coming & call back the function which should add the new user to the stream!
const APP_ID = "fe45f285661941ada5ef5d451fe8f626"
const CHANNEL = "main"
const TOKEN = "006fe45f285661941ada5ef5d451fe8f626IABxEPnj4KCl8i4+gcrg2F7Cc+nmjmOiRWq49ICnSOHfdGTNKL8AAAAAEACXVkQu42OcYgEAAQC9Y5xi"
const client = AgoraRTC.createClient({mode:"rtc",codec:"vp8"})
let localTracks = []
let remoteUsers = {}
let UID
let joinAndDisplayLocalStreams = async ()=> {
client.on("user-published",handleUserJoined)
UID = await client.join(APP_ID,CHANNEL,TOKEN,null)
localTracks = await AgoraRTC.createMicrophoneAndCameraTracks()
let player = ` <div class="video-container" id="user-container-${UID}">
<div class="name-wrapper"><span class="user-name">My name</span></div>
<div class="video-player" id="user-${UID}"></div>
</div>`
document.getElementById("video-streams").insertAdjacentHTML("beforeend",player)
localTracks[1].play(`user-${UID}`)
await client.publish([localTracks[0],localTracks[1]])
}
let handleUserJoined = async(user,mediaType)=>{
remoteUsers[user.uid]= user
await client.subscribe(user,mediaType)
console.log(mediaType)
if(mediaType==="video"){
let player = document.getElementById(`user-container-${user.uid}`)
if(player!=null){
player.remove()
}
player = `<div class="video-container" id="user-container-${user.uid}">
<div class="name-wrapper"><span class="user-name">My name</span></div>
<div class="video-player" id="user-${user.uid}"></div>
</div>`
document.getElementById("video-streams").insertAdjacentElement("beforeend",player)
user.videoTrack.play(`user-${user.uid}`)
}
if(mediaType==="audio"){
user.audioTrack.play()
}
}
joinAndDisplayLocalStreams()
I am working with Github API and I am displaying the data from users. When the date is displayed I want it to only have the date user.created_at with DD/MM/YY and not the whole hour. Also when the user has no Biography user.bio the data appears as null, and I want it to display the text 'The user has no bio'. I have not figured out the way to do both things so if you could help me I would very much appreciate it
Here below the code:
const APIURL = 'https://api.github.com/users/'
const main = document.getElementById('main')
const form = document.getElementById('form')
const search = document.getElementById('search')
async function getUser(username){
try{
const { data } = await axios(APIURL + username)
createUserCard(data)
getRepos(username)
}catch (err){
if(err.response.status == 404){
createErrorCard('No profile with this Username')
}
}
}
async function getRepos(username){
try{
const { data } = await axios(APIURL + username + '/repos?sort=created')
addReposToCard(data)
}catch (err){
createErrorCard('Problem Fetching Repos')
}
}
function createUserCard(user){
const cardHTML = `
<div class="card">
<div>
<img src="${user.avatar_url}" alt="${user.name}" class="avatar">
</div>
<div class="user-info">
<div class="header">
<h2>${user.name}</h2>
<p class="date">Joined ${user.created_at}</p>
</div>
<p>#${user.login}</p>
<p>${user.bio}</p>
<ul>
<div class="list">
<li>${user.followers} </li>
<li>${user.following} </li>
<li>${user.public_repos} </li>
</div>
<div class="list-names">
<strong>Followers</strong>
<strong>Following</strong>
<strong>Repos</strong>
</div>
</ul>
<div class="additional-data">
<p class="location"><img src="./img/location.svg" alt="Location" class="img" /> ${user.location} </p>
<img src="./img/link.svg" alt="Link" class="img" />${user.html_url}
</div>
<div id="repos"></div>
</div>
</div>`
main.innerHTML = cardHTML
}
function createErrorCard(msg){
const cardHTML = `
<div class="card">
<h1>${msg}</h1>
</div>
`
main.innerHTML = cardHTML
}
function addReposToCard(repos){
const reposEl = document.getElementById('repos')
repos
.slice(0, 5)
.forEach(repo => {
const repoEl = document.createElement('a')
repoEl.classList.add('repo')
repoEl.href = repo.html_url
repoEl.target = '_black'
repoEl.innerText = repo.name
reposEl.appendChild(repoEl)
})
}
form.addEventListener('submit', (e) => {
e.preventDefault()
const user = search.value
if(user){
getUser(user)
search.value = ''
}
})
in the case of user.bio you can use the ternary operator:
(conditional)?value when conditional true: value when conditional false
for example:
${(user.bio!="null")?user.bio:"The user has no bio"}
or
${(user.bio!=null)?user.bio:"The user has no bio"}
in the case of date github helps us giving us a formated string that we can cast to a date using new Date() and format it using Date.prototype.toLocaleString()
${(new Date(user.created_at)).toLocaleDateString()}
in this case is not needed to pass parameters to toLocaleDateString() but I encourage you to read about this function here
I want to make a real-time count of the total function of the javascript that all user can see when he visit my site.
For example, there are 3 visitors now I want to total how many successful Javascript executed they do that the count don't reset when the page refresh and are all visible to all user who visit.
html:
<div class="row">
<div class="col">
<div class="card-profile-stats d-flex justify-content-center mt-md-5">
<div>
<span class="heading" id="count1">0</span>
<span class="badge badge-success">Count 1</span>
</div>
<div>
<span class="heading" id="count2">0</span>
<span class="badge badge-danger">Count 2</span>
</div>
<div>
<span class="heading" id="count3">0</span>
<span class="badge badge-info">Count 3</span>
</div>
<div>
<span class="heading" id="all">0</span>
<span class="badge badge-info">Total</span>
</div>
</div>
</div>
</div>
js:
function startfunc() {
var xs = 0;
var cb = 0;
var fp = 0;
$.ajax({
url: 'urlhere.php',
type: 'GET',
async: true,
success: //some of my code here
var total = parseInt(xs) + parseInt(cb) + parseInt(fp);
$('#count1').html(xs);
$('#count2').html(cb);
$('#count3').html(fp);
$('#all').html(total);
Assuming that you have a database that is storing the values (this would be the only way to store the total values) then you would create an interval timer that would perform the http request to get the results on frequency that is not too often.
The example I'm giving is in pure JavaScript, so it should work. You don't need jQuery for this.
Promise Method:
File: script.js
// Code to execute when window loaded
window.addEventListener('load', () => {
// Main function to retrieve results
const getResults = () => {
fetch('/url/to/getResults.php')
.then(response => {
const json = response.json();
if (response.ok) {
return json;
}
return json.then(data => Promise.reject(data));
})
.then(jsonData => {
const total = parseInt(jsonData.xs) + parseInt(jsonData.cb) + parseInt(jsonData.fp);
document.querySelector('#count1').innerHTML = jsonData.xs;
document.querySelector('#count2').innerHTML = jsonData.cb;
document.querySelector('#count3').innerHTML = jsonData.fp;
document.querySelector('#total').innerHTML = total;
})
.catch(error => {
console.log('ERROR', error);
});
};
// Get an update results every 60 seconds
const interval = setInterval(getResults, 60000);
});
Async/Await Method:
window.addEventListener('load', () => {
// Main function to retrieve results
const getResults = async () => {
try {
const response = await fetch('/url/to/getResults.php');
const responseJSON = await response.json();
const total = parseInt(jsonData.xs) + parseInt(jsonData.cb) + parseInt(jsonData.fp);
document.querySelector('#count1').innerHTML = jsonData.xs;
document.querySelector('#count2').innerHTML = jsonData.cb;
document.querySelector('#count3').innerHTML = jsonData.fp;
document.querySelector('#total').innerHTML = total;
} catch (error) {
console.log('ERROR', error);
}
};
// Get an update results every 60 seconds
const interval = setInterval(await getResults, 60000);
});
The click on the div element with role='button' isn't operate.I need to click on the icon, but I can't do it.
html:
<div class="list">
<div class="item">
<div role="button" tabindex="-1">
<strong>ItemName2</strong>
</div>
<div class="d">
<div class="item-icon" role="button" tabindex="-1" style="display: none">
<i aria-label="icon: edit" class="edit"></i>
</div>
</div>
</div>
<div class="item"> ... </div>
<div class="item"> ... </div>
<div class="item"> ... </div>
</div>
js:
try {
await driver.get("http://127.0.0.1");
let findButtons = await driver.findElements(By.tagName('strong'));
let buttons = findButtons.map(elem => elem.getText());
const allButtons = await Promise.all(buttons);
console.log(allButtons); // It is displayed all button values, such as ItemName1
let tButton;
for (let i = 0; i < findButtons.length; i++) {
if (allButtons[i] == 'ItemName2') {
tButton = await findButtons[i];
tButton.click(); // I try to click on this button, where value = ItemName2
console.log(allButtons[i]); // It is displayed button value 'ItemName2'
}}}
Console error:
(node:12254) UnhandledPromiseRejectionWarning: StaleElementReferenceError: stale element reference: element is not attached to the page document
You are getting stale element exception because you are trying to get the element with old references. Each time you click on the element in your loop, the elements reference will be updated and allButtons[i] does not work. In order to handle this you have to get the latest refers of buttons. Try the below.
js:
const { By, Key, until } = require("selenium-webdriver");
const webdriver = require("selenium-webdriver");
require("chromedriver");
async () => {
let driver = await new webdriver.Builder().forBrowser("chrome").build();
try {
await driver.get("http://10.203.201.77:8000/login");
let findButtons = await driver.findElements(By.tagName('strong'));
let buttons = findButtons.map(elem => elem.getText());
const allButtons = await Promise.all(buttons);
console.log(allButtons); // It is displayed all button values, such as ItemName1
let tButton;
for (let i = 0; i < findButtons.length; i++) {
buttons = findButtons.map(elem => elem.getText()); # getting the button so that the elements refererence will refresh
if (allButtons[i] == 'ItemName2') {
tButton = await findButtons[i];
tButton.click(); // I try to click on this button, where value = ItemName2
console.log(allButtons[i]); // It is displayed button value 'ItemName2'
}
}
console.log("DONE");
} catch (e) {
console.log(e);
} finally {
await driver.quit();
}
}
}
I found solution:
let findButtons = await driver.findElements(By.tagName('strong'));
let buttons = findButtons.map(async elem => await elem.getText()); // I add async & await
const allButtons = await Promise.all(buttons);
console.log(allButtons); // There are all itemName