I'm messing around with the Harry Potter API (just to learn how API's work), and have successfully gotten the images from the site onto mine. But I have created like 8 functions to do it and I feel like it could be done a lot easier. Here is the code:
JS:
// API
url = "http://hp-api.herokuapp.com/api/characters";
fetch(url)
.then(function(response){
return response.json();
})
.then(function(data){
display_image(data[1].image);
display_image2(data[2].image);
display_image3(data[3].image);
display_image4(data[4].image);
display_image5(data[5].image);
display_image6(data[6].image);
display_image7(data[7].image);
display_image8(data[8].image);
})
.catch(function(error){
console.log("Error: " error)
});
function display_image(image_url){
document.getElementById("image1").src = image_url;
}
function display_image2(image_url){
document.getElementById("image2").src = image_url;
}
function display_image3(image_url){
document.getElementById("image3").src = image_url;
}
function display_image4(image_url){
document.getElementById("image4").src = image_url;
}
function display_image5(image_url){
document.getElementById("image5").src = image_url;
}
function display_image6(image_url){
document.getElementById("image6").src = image_url;
}
function display_image7(image_url){
document.getElementById("image7").src = image_url;
}
function display_image8(image_url){
document.getElementById("image8").src = image_url;
}
HTML:
<div class="popularContainer">
<div class="grid-1">
<img width="100%" alt="" id="image1">
</div>
<div class="grid-2">
<img width="100%" alt="" id="image2">
</div>
<div class="grid-3">
<img width="100%" alt="" id="image3">
</div>
<div class="grid-4">
<img width="100%" alt="" id="image4">
</div>
<div class="grid-5">
<img width="100%" alt="" id="image5">
</div>
<div class="grid-6">
<img width="100%" alt="" id="image6">
</div>
<div class="grid-6">
<img width="100%" alt="" id="image7">
</div>
<div class="grid-6">
<img width="100%" alt="" id="image8">
</div>
</div>
Also, more of a "if I do this" thing than a practical use right now. But let's say I put a random index on the data and got a random picture everytime the user reloaded the page. Is there a way to distinguish if there are duplicates and have one or more of them rerun so it's not a duplicate anymore? Also could I make it to where if one was a certain character it would not show up (with .style.display maybe)?
Anyways, any help is appreciated.
CodePudding user response:
Come up with an array (or collection) of the <img>
s to populate, and then all you need to do is iterate over the indicies of the response.
You also probably want to start at [0]
, not at [1]
- JavaScript arrays are zero-indexed, not one-indexed.
const images = document.querySelectorAll('.popularContainer img');
fetch(url)
.then(response => response.json())
.then((data) => {
data.forEach((obj, i) => {
images[i].src = obj.image;
});
});
If the response contains more than 8 characters, slice to take only the first 8.
data.slice(0, 8).forEach((obj, i) => {
But let's say I put a random index on the data and got a random picture everytime the user reloaded the page. Is there a way to distinguish if there are duplicates and have one or more of them rerun so it's not a duplicate anymore?
When the response comes back the first time, you could put it into Local Storage. When you pick an image to display, remove it from the array of data and update the storage. On further loads, take the storage item instead of fetching again.
CodePudding user response:
Creating the images from the returned response.json()
in the then
handler is one of the more straightforward ways this can be achieved. Using document.createElement("img")
can be used to create each image tag. Then, appendChild
can be used to append the images to the container directly without creating additional functions:
data.forEach((imgData, index) => {
let img = document.createElement("img");
img.id = `image${index}`;
img.src = imgData.image;
imgContainer.appendChild(img);
});
const imgContainer = document.getElementById("container");
const url = "http://hp-api.herokuapp.com/api/characters";
fetch(url)
.then(function(response) {
return response.json();
}).then(function(data) {
/* Slicing the data array down to only 8 elements will enable us to
show just the first 8 images */
const littleD = data.slice(0, 8);
littleD.forEach((imgData, index) => {
let img = document.createElement("img");
img.id = `image${index}`;
img.src = imgData.image;
imgContainer.appendChild(img);
});
})
.catch(function(error) {
console.log("Error: " error)
});
img {
width: 100%
}
<div id="container">
</div>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>