How do I make images from this waifu API appear on page? - javascript

I've been stuck on this Waifu API for a bit now and want to ask for help.
I can get the JSON tags in the console and from there I'm able to navigate, click on the image, and see it. But I'm having trouble formatting it on the page with each click.
I know it's a stupid question, I just wanna make my friends at work laugh but also LEARN WHY IT ISN'T WORKING. :/
thank you for your time
<!-- ---waifuthingy----- -->
<div id="waifuContainer" class="container mt-5 text-center">
<h1 class="display-5 text-warning" id="dadJokeFont">Click for waifu:</h1>
<button id="waifuButton" class="btn btn-warning mt-5">uWu</button>
<div id="waifuImage" >
<img id="waifus" src="" alt=""> </div>
</div>
<!-- ----letmebe---- -->
// Waifu Image API
const waifuImage = document.querySelector('#waifuImage');
const waifuButton = document.querySelector('#waifuButton');
const makeImages = (waifus) => {
for(let result of waifus) {
const img = document.createElement('IMG');
img.src.url = result.show.image.medium;
document.body.append(img);
}
}
waifuButton.addEventListener('click', () => {
fetch('https://api.waifu.im/random')
.then(res => res.json())
.then(res => {
console.log(res.images)
waifuImage.src = res.url;
waifus = waifuImage;
})
.catch(err=>console.log(err))
})

Issues:
You are trying to set the src on the div rather than img
You are trying to set res.url, But the res doesn't have a URL. URL is in res.images[0].url.
const waifuImage = document.querySelector('#waifus');
const waifuButton = document.querySelector('#waifuButton');
const makeImages = (waifus) => {
for (let result of waifus) {
const img = document.createElement('IMG');
img.src.url = result.show.image.medium;
document.body.append(img);
}
}
waifuButton.addEventListener('click', () => {
fetch('https://api.waifu.im/random')
.then(res => res.json())
.then(res => {
waifuImage.src = res.images[0].url;
})
.catch(err => console.log(err))
})
#waifus {
width: 100%;
object-fit: contain;
}
<div id="waifuContainer" class="container mt-5 text-center">
<h1 class="display-5 text-warning" id="dadJokeFont">Click for waifu:</h1>
<button id="waifuButton" class="btn btn-warning mt-5">uWu</button>
<div id="waifuImage">
<img id="waifus" src="" alt="">
</div>
</div>

Related

zxing invoking unepexected warning in browser console

The browser console is reporting immediately after activating the camera on the device
Started continous decode from camera with id BGOlLyxMumeB0YGZoWhjlsR1atGM5DEXtxqIrhEmoqk=
It was not possible to play the video.
The camera is however running in the <video tag.
The error references library#latest:15:31010 Error loading this URI: Unknown source
Follows is the HTML code on the page where the error is generated.
What could be the source of the error / or how could it be overcome?
<div id='security_check'></div>
<div class='grid-x grid-padding-x'>
<div class='cell small-12 '>
<label>scan:</label>
<pre><code id="result"></code></pre>
</div>
<div class='cell small-2 '>
</div>
</div>
<div class='grid-x grid-padding-x'>
<div class='cell small-12 '>
<div id="sourceSelectPanel" style="display:none">
<label for="sourceSelect">change_video_source:</label>
<select id="sourceSelect" style="max-width:400px">
</select>
</div>
</div>
</div>
<div class='grid-x grid-padding-x'>
<div class='cell small-6'>
<a class="button" id="resetButton">Stop</a>
</div>
<div class='cell small-6'>
<a class="button" id="startButton">Go</a>
</div>
</div>
<div class='grid-x grid-padding-x'>
<video id="video" width="320" height="180" style="border: 1px solid gray"></video>
</div>
</div>
<button class="close-button" data-close aria-label="Close modal" type="button">
<span aria-hidden="true">×</span>
</button>
<script type="text/javascript" src="https://unpkg.com/#zxing/library#latest"></script>
<script type="text/javascript">
window.addEventListener('load', function () {
let selectedDeviceId;
const codeReader = new ZXing.BrowserMultiFormatReader()
console.log('ZXing code reader initialized')
codeReader.getVideoInputDevices()
.then((videoInputDevices) => {
const sourceSelect = document.getElementById('sourceSelect')
selectedDeviceId = videoInputDevices[0].deviceId
if (videoInputDevices.length >= 1) {
videoInputDevices.forEach((element) => {
const sourceOption = document.createElement('option')
sourceOption.text = element.label
sourceOption.value = element.deviceId
sourceSelect.appendChild(sourceOption)
})
sourceSelect.onchange = () => {
selectedDeviceId = sourceSelect.value;
};
const sourceSelectPanel = document.getElementById('sourceSelectPanel')
sourceSelectPanel.style.display = 'block'
}
document.getElementById('startButton').addEventListener('click', () => {
codeReader.decodeFromVideoDevice(selectedDeviceId, 'video', (result, err) => {
if (result) {
console.log(result)
document.getElementById('result').textContent = result.text
let formData = new FormData();
let CodeParams = {
code_data: result.text,
item_id: item.id
};
formData.append("code_json_data", JSON.stringify(CodeParams));
Rails.ajax({
url: "update_q",
type: "post",
data: formData
});
}
if (err && !(err instanceof ZXing.NotFoundException)) {
console.error(err)
document.getElementById('result').textContent = err
}
})
console.log(`Started continous decode from camera with id ${selectedDeviceId}`)
})
document.getElementById('resetButton').addEventListener('click', () => {
codeReader.reset()
document.getElementById('result').textContent = '';
console.log('Reset.')
})
})
.catch((err) => {
console.error(err)
})
})
</script>

Trouble rendering items from api feed

I am trying to display the latest and top stories on a single homepage using the hacker news API feed. I am using the .map so the code will loop over each story and display it all in a div with an id of output.
From what I am able to see I need to call the first API feed that will give me the day's top 500 results. The first API will only return story IDs as integers. I then need to make a 2nd API call using each story id from the original API call and map over it to get the corresponding data to each story to display on my site.
The code is working and the results are being displayed however when I switch between the latest stories and the top stories I keep getting different results at the top. Should I be using async and await somewhere In my code?
function getNewPosts() {
document.getElementById('output').innerHTML = ``;
fetch('https://hacker-news.firebaseio.com/v0/newstories.json?print=pretty')
.then(response => response.json())
.then(storyIds => {
storyIds.map(function (id) {
return (
fetch(`https://hacker-news.firebaseio.com/v0/item/${id}.json?print=pretty`)
.then(response => response.json())
.then(story => {
// Display time human readable
let unixTimestamp = story.time;
let milliseconds = unixTimestamp * 1000;
let dateObject = new Date(milliseconds);
let humanDateFormat = dateObject.toLocaleString();
document.getElementById('output').innerHTML += `
<div class="card mb-3">
<h5 id="post-title" class="card-header data-title mb-1">${story.title}</h5>
<div class="card-body">
<p class="off-white-text mb-0">${story.type} by: ${story.by}</p>
<p class="off-white-text mb-0">posted: ${humanDateFormat}</p>
<p class="off-white-text mb-0">link to article:<a class="post-url" href="${story.url}" target="_blank"> Click here</a></p>
</div>
</div>
`
})
)
})
})
}
function getTopPosts() {
document.getElementById('output').innerHTML = ``;
fetch('https://hacker-news.firebaseio.com/v0/topstories.json?print=pretty')
.then(response => response.json())
.then(storyIds => {
storyIds.map(function (id) {
return (
fetch(`https://hacker-news.firebaseio.com/v0/item/${id}.json?print=pretty`)
.then(response => response.json())
.then(story => {
// Display time human readable
let unixTimestamp = story.time;
let milliseconds = unixTimestamp * 1000;
let dateObject = new Date(milliseconds);
let humanDateFormat = dateObject.toLocaleString();
document.getElementById('output').innerHTML += `
<div class="card mb-3">
<h5 id="post-title" class="card-header data-title mb-1">${story.title}</h5>
<div class="card-body">
<p class="mb-0 off-white-text">${story.type} by: ${story.by}</p>
<p class="mb-0 off-white-text">Posted: ${humanDateFormat}</p>
<p class="mb-0 off-white-text">Link to article:<a class="post-url" href="${story.url}" target="_blank"> Click here</a></p>
</div>
</div>
`
})
)
})
})
}
The user is able to switch between the top and newest posts by clicking on a button for each on the homepage
<!-- Action buttons -->
<div class="row">
<div class="col-12 col-md-12 text-center">
<button id="getPosts" class="btn my-1" onclick="getNewPosts()">Read Latest News</button>
<button id="getPosts" class="btn my-1" onclick="getTopPosts()">Read Top News</button>
<button id="getPosts" class="btn my-1" onclick="clearNews()">Reset All News</button>
<hr class="text-white">
</div>
</div>
Thanks for any help in advance

Passing multiple variables into JavaScript function in Template Literals (DOM)

I am looping through an array of objects (rendering data coming from an API) via Vanilla JavaScript (DOM). And I want to pass more than one value (Product ID, Product Name .. etc) to a function triggered in the event of a click button. saveProduct(${proInfo}) as it shown below (proInfo is an object).
The problem is I have been able to pass ONLY ONE value to this function. I tried to pass the variable as an object but it didn't work and got the error (index):1 Uncaught SyntaxError: Unexpected end of input
var shopNcounter = 0;
const baseURL = "***";
const idsArray = [];
const divRow = document.querySelector(".row");
const buttonContainer = document.querySelector("#button-container")
//create column div
function createDiv() {
const div = document.createElement("div");
div.classList.add("col-xl-3");
div.classList.add("col-md-6");
div.classList.add("col-sm-12");
return div;
}
async function getData(id) {
shopNcounter ++;
console.log(shopNcounter);
if(shopNcounter > 5) {
getProInfo(id);
return;
} else if (shopNcounter > 4) {
getProducts(id);
return;
}
idsArray.push(id);
console.log(id);
console.log(idsArray);
if(idsArray.length > 10) {
idsArray.splice(0,6);
}
const api = `**shop=${shopNcounter}&id=${id}`;
try {
const response = await fetch(api);
const data = await response.json();
divRow.innerHTML = "";
if (shopNcounter > 1) {
buttonContainer.innerHTML = `
<button class="btn btn-lg btn-warning px-5" onclick="moveBack(${idsArray[idsArray.length-2]})">رجوع</button>
`
} else {
buttonContainer.innerHTML = "";
}
//mapping through data
data.map(item => {
const div = createDiv();
divRow.appendChild(div);
div.innerHTML+=`
<div class="card text-center h-100 mx-auto border-white shadow" style="width: 16rem;">
<img src="${baseURL + item.image}" class="card-img-top mx-auto" alt="...">
<div class="card-body">
<a onclick=handleClick(${item.id}) class="btn btn-outline-dark px-5 mt-4" id="goToItemButton">${item.name}</a>
</div>
</div>
`;
});
} catch(error) {console.log(error);}
}
getData(0);
async function getProducts(id) {
//shop > 4 = 5
console.log("Get Product is being executing");
const apiProducts = `**product?id=${id}`;
try {
const response = await fetch(apiProducts);
const data = await response.json();
console.log(data);
divRow.innerHTML = "";
//mapping through data
data.map((item, index) => {
var proInfo = {
pid: item.PID,
pname: item.PName
}
const div = createDiv();
divRow.appendChild(div);
div.innerHTML+=`
<div class="card text-center h-100 mx-auto border-white shadow" style="width: 16rem;">
<img src="${baseURL + item.image}" class="card-img-top mx-auto" alt="...">
<div class="card-body">
<h5>${item.PName}</h5>
<p class="product-price">Price: ${item.PSelPrice}</p>
<a onclick=saveProduct(${item.PID}) class="btn btn-danger px-5 mt-4"> Add to Card </a>
</div>
</div>
`;
});
} catch(error) {
console.log(error);
}
}
function moveBack(id) {
shopNcounter = shopNcounter -2;
getData(id);
}
function handleClick(id) {
let clickedButton = document.querySelector("#goToItemButton");
clickedButton.onclick = "";
getData(id);
}
function saveProduct(g) {
console.log(g);
}
your code should not result in the error you see
However you can make your life easier using delegation
do this
document.getElementById("container").innerHTML = data.map((item,i) => `<div class="card text-center h-100 mx-auto border-white shadow" style="width: 16rem;">
<img src="${baseURL + item.image}" class="card-img-top mx-auto" alt="...">
<div class="card-body">
<h5>${item.PName}</h5>
<p class="product-price">Price: ${item.PSelPrice}</p>
<a data-id="${i}" class="add btn btn-danger px-5 mt-4"> Add to Card </a>
</div>
</div>`).join("");
Have this
document.getElementById("container").addEventListener("click",function(e) {
const tgt = e.target.closest("a");
if (tgt && tgt.className.contains("add")) {
const item = data[tgt.dataset.id]
// here you can add the item
saveProduct({pid: item.PID,pname: item.PName })
}
})

.click() only firing once then no more after that unless i refresh the whole page and doesn't render at all if i call $(document).ready()

I am trying to retrieve a quote and its author from a JSON file, the problem I am having is that once I click the button once, then the event is fired but only once and no more after that. Equally, when I call $(document).ready() the button doesn't fire at all.
I know that it is something to do with the way I am collecting the data from the JSON file (is an array of objects with text, author keys), and then subsequently calling the fetch when I want to retrieve a new quote with the correct author.
// https://type.fit/api/quotes //
// api link for quotes //
const button = document.getElementById('new-quote');
const baseUrl = 'https://type.fit/api/quotes';
let randomNumber = Math.floor(Math.random() * 100);
function getQuote() {
fetch(baseUrl)
fetch(baseUrl)
.then(response => response.json())
.then(quote => $('#text-output').text(quote[randomNumber].text))
};
function getAuthor() {
fetch(baseUrl)
.then(response => response.json())
.then(quote => $('#author').text(quote[randomNumber].author))
};
function renderQuoteToPage() {
getQuote();
getAuthor();
}
$('#new-quote').click(renderQuoteToPage);
$(document).ready(renderQuoteToPage);
body {
width: 100%;
height: auto;
}
#outer-wrapper {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="outer-wrapper" class="container-fluid">
<div id="quote-box" class="card w-50">
<div class="card-body">
<div class="row">
<div class="col">
<div id="text">
<p id="text-output"></p>
</div>
</div>
</div>
<div class="row">
<div class="col">
Tweet
</div>
<div class="col">
<div id="author">Author</div>
</div>
</div>
<div class="row">
<div class="col">
<button id="new-quote">New quote</button>
</div>
</div>
</div>
</div>
</div>
You are calling the functions when you attach the handlers, so they are invoked without the appropriate handler being attached, and just once.
You need just the function definition:
$('#new-quote').click(renderQuoteToPage);
...
$(document).ready(renderQuoteOnPageLoad);
Edit: You also need to set randomNumber on each getQuote() call
// https://type.fit/api/quotes //
// api link for quotes //
const button = document.getElementById('new-quote');
const baseUrl = 'https://type.fit/api/quotes';
let randomNumber
function getQuote() {
randomNumber = Math.floor(Math.random() * 100);
fetch(baseUrl)
.then(response => response.json())
.then(quote => $('#text-output').text(quote[randomNumber].text))
};
function getAuthor() {
fetch(baseUrl)
.then(response => response.json())
.then(quote => $('#author').text(quote[randomNumber].author))
};
function renderQuoteToPage() {
getQuote();
getAuthor();
}
$('#new-quote').click(renderQuoteToPage);
$(document).ready(renderQuoteToPage);
body {
width: 100%;
height: auto;
}
#outer-wrapper {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="outer-wrapper" class="container-fluid">
<div id="quote-box" class="card w-50">
<div class="card-body">
<div class="row">
<div class="col">
<div id="text">
<p id="text-output"></p>
</div>
</div>
</div>
<div class="row">
<div class="col">
Tweet
</div>
<div class="col">
<div id="author">Author</div>
</div>
</div>
<div class="row">
<div class="col">
<button id="new-quote">New quote</button>
</div>
</div>
</div>
</div>
</div>
Few changes in your script and its done.
<script>
const button = document.getElementById('new-quote');
const baseUrl = 'https://type.fit/api/quotes';
let randomNumber;
function getQuote() {
fetch(baseUrl)
.then(response => response.json())
.then(quote => $('#text-output').text(quote[randomNumber].text))
};
function getAuthor() {
fetch(baseUrl)
.then(response => response.json())
.then(quote => $('#author').text(quote[randomNumber].author))
};
function renderQuoteOnPageLoad() {
randomNumber = Math.floor(Math.random() * 100);
getQuote();
getAuthor();
}
$(document).ready(function(){
renderQuoteOnPageLoad();
});
$(document).on("click","#new-quote",function(){
renderQuoteOnPageLoad()
})
</script>
Example Fiddle

how to view items from api and add item to cart

im fetching items image , name ,price ,about from API
i fetched each item and added it in html tag the problem when i press add to cart button nothing adding
i tried onclick function on the button and call item by id
html page
<div id="api-1" class="images full">
</div>
js file
window.onload = function(){
const name = document.getElementById('api-1');
const tableItems = document.getElementById('item');
const cartContent = document.getElementsByClassName('table-cart');
fetch('https://us-central1-guitar-chord-de94e.cloudfunctions.net/products')
.then(response => response.json())
.then(items => {
let html = '';
items.forEach(item =>{
// console.log(item.items.name)
html += `
<div class="container">
<img src=${item.items.image} class="item">
<div class="overlay">
<p style="color:white">${item.items.name}</p>
<p style="color: white;font-weight: bold;font-size: 17px">price: ${item.items.price}</p>
<div style="margin-top:60px;">
<button onclick="addToCart()" style="background-color: gold;margin:0%;">add <img width="16px" src="./image/icons/shopping-cart.png" alt=""></button>
</div>
</div>
</div>
`;
name.innerHTML= html;
})
});
}
function addToCart(){
fetch('https://us-central1-guitar-chord-de94e.cloudfunctions.net/products')
.then(response => response.json())
.then(sys => {
sys.forEach(item =>{ console.log(item.sys);
});
});
}
You have to pass the id, button click handler like in below code.
<button onclick="addToCart(${item.sys.id})" style="background-color: gold;margin:0%;"></button>
Here's a working pen. https://codepen.io/anon/pen/jjojVm
I am capturing id of the clicked item in addToCart function. Using that id, you can maintain a cart in the same page or you can goto to different page passing the same id in URL depending on your requirement.

Categories