I'm trying to access the image property from the array of objects from NASA API , so it can be displayed randomly when I click on a button
I want a different image to be shown whenever I click a button. The images are from an array of objects from NASA api.
document.querySelector('button').addEventListener('click', getFetch)
function getFetch() {
const url = 'https://api.nasa.gov/mars-photos/api/v1/rovers/curiosity/photos?sol=1000&api_key=1wCuyjoxfSrvsEbUpfWJvuBEMB5I0x79kXS0pfrg'
fetch(url)
.then(res => res.json()) // parse response as JSON
.then(data => {
console.log(data)
data.photos.forEach(element => {
document.querySelector('img').src = element.img_src
f
});
})
.catch(err => {
console.log(`error ${err}`)
});
}
CodePudding user response:
I'd say that you are doing it the wrong way around - don't fetch up to 1000 images on click, fetch them first and cycle through them on click.
const button = document.querySelector('button');
const img = document.querySelector('img');
const imgUrl = 'https://api.nasa.gov/mars-photos/api/v1/rovers/curiosity/photos?sol=1000&api_key=1wCuyjoxfSrvsEbUpfWJvuBEMB5I0x79kXS0pfrg'
const makeImgCycler = (images) => {
return () => {
const n = Math.floor(Math.random() * images.length);
return images[n];
};
};
const fetchImgs = (url) => {
return fetch(url).then(r => r.json());
};
fetchImgs(imgUrl).then(data => {
const nextImage = makeImgCycler(data.photos);
button.disabled = null;
button.addEventListener('click', () => {
img.src = nextImage().img_src;
});
});
<button disabled>Next</button>
<img alt="">
Hint
The "Next" button is initially disabled until the images are loaded.
EDIT
Made makeImgCycler
/nextImage
return a random image. Not checking if it returns the same random image on subsequent clicks, though.
CodePudding user response:
This is not fast so we fetch first and then allow showing
I have now implemented that we show unique random images until we have shown all, then we again show unique random images from a copy of the original array.
const randomImage = document.getElementById("randomImage");
const btn = document.querySelector('button');
const url = 'https://api.nasa.gov/mars-photos/api/v1/rovers/curiosity/photos?sol=1000&api_key=1wCuyjoxfSrvsEbUpfWJvuBEMB5I0x79kXS0pfrg'
let shown = [];
let images = [];
const getUnique = () => {
if (images.length === 0) images = shown.splice(0, shown.length); // copy back
const rnd = Math.floor(Math.random() * images.length);
const image = images.splice(rnd, 1)[0];
shown.push(image)
return image;
};
fetch(url)
.then(res => res.json()) // parse response as JSON
.then(data => {
images = data.photos.map(element => element.img_src) // .slice(0, 3); // for testing
btn.textContent = "Show image";
btn.addEventListener('click', function() {
randomImage.src = getUnique();
})
})
.catch(err => {
console.log(`error ${err}`)
});
<button type="button">Please wait...</button>
<img id="randomImage" src="" />
Previous simpler version
const randomImage = document.getElementById("randomImage");
const btn = document.querySelector('button');
const url = 'https://api.nasa.gov/mars-photos/api/v1/rovers/curiosity/photos?sol=1000&api_key=1wCuyjoxfSrvsEbUpfWJvuBEMB5I0x79kXS0pfrg'
fetch(url)
.then(res => res.json()) // parse response as JSON
.then(data => {
let images = data.photos.map(element => element.img_src);
btn.textContent = "Show image";
btn.addEventListener('click', function() {
const rnd = Math.floor(Math.random() * images.length);
randomImage.src = images[rnd];
})
})
.catch(err => {
console.log(`error ${err}`)
});
<button type="button">Please wait...</button>
<img id="randomImage" src="" />
CodePudding user response:
First of all, please remove your API keys when posting to public forums.
The reason is that you are applying the image url to the same image object and so the last image to be iterated will be the one displayed. My recommendation would be to cache the images in an array somewhere and then choose a new random image when you click the button again.
The API should not have to be called more than once since it's making a HTTP request and will feel slow and sluggish depending on the distance from the user and the NASA servers
CodePudding user response:
Your API is providing object array. If you want to show random image from an array you can use some like below:
let show = photos[Math.floor(Math.random() * photos.length)];