I am using fetch within vanilla JavaScript to get data from an API that shows US holidays, sadly am having an issue with cycling through the array. I cannot seem to get the variables to work within the then statement. Whenever I click the next button I had crated, var holidayNum does go up by +1 but var holiday = holidays[holidayNum].name; does not change to show new item within the list from the API array.
I am certain there is something simple I am missing here, I am new to using .then, have been trying to search for an answer all over but cannot, may be due to lack of better words?
Much appreciated for anyone who can assist or possibly point me in the right direction.
Here is my code I am trying to get to work:
<html>
<head>
<title>API TEST</title>
</head>
<body>
<h1>Holiday:</h1>
<ul class="holidayList"></ul>
<button class="nextBtn">Next</button>
<script>
var holidayNum = 0;
function nextHoliday() {
holidayNum = holidayNum + 1;
alert(holidayNum)
}
fetch("https://date.nager.at/api/v2/publicholidays/2020/US")
.then((res) => res.json())
.then((data) => {
holidays = data;
})
.then(() => {
console.log(holidays);
var holiday = holidays[holidayNum].name;
var markup = `<li>${holiday}</li>`;
document.querySelector(".holidayList").insertAdjacentHTML("beforeend", markup);
})
document.querySelector(".nextBtn").addEventListener("click", nextHoliday);
</script>
</body>
</html>
I had come up with a solution myself, please see code below, but the accepted answer by @Alexander Nenashev is WAY cleaner and usable.
(Please note in my script below that works, I updated it from using a list item to just changing value of <p class="holidayName"></p>.
<html>
<head>
<title>API TEST</title>
</head>
<body>
<h1>Holiday:</h1>
<p class="holidayName"></p>
<button class="nextBtn">Next</button>
<script>
var holidayNum = 0;
fetch("https://date.nager.at/api/v2/publicholidays/2020/US")
.then((res) => res.json())
.then((data) => {
holidays = data;
})
.then(() => {
console.log(holidays);
var holiday = holidays[holidayNum].name;
var markup = `${holiday}`;
document.querySelector(".holidayName").innerHTML = markup;
function nextHoliday() {
holidayNum = holidayNum + 1;
console.log(holidayNum)
var holiday = holidays[holidayNum].name;
var markup = `${holiday}`;
document.querySelector(".holidayName").innerHTML = markup;
}
document.querySelector(".nextBtn").addEventListener("click", nextHoliday);
})
</script>
</body>
</html>
>Solution :
I suggest favor async/await instead of .then(). Makes code more readable, maintainable and less buggy. To use await without async in the top level of your script add type="module".
h1{
font-size:smaller;
margin:0;
}
.holidayList{
display: flex;
flex-flow: column;
flex-wrap: wrap;
height:90px;
}
<h1>Holiday:</h1>
<ul class="holidayList"></ul>
<button class="nextBtn">Next</button>
<script type="module">
const response = await fetch("https://date.nager.at/api/v2/publicholidays/2020/US")
const holidays = await response.json();
let currentHolidayIndex = 0;
const nextHoliday = () => document.querySelector(".holidayList").insertAdjacentHTML("beforeend", `<li>${holidays[currentHolidayIndex++].name}</li>`);
nextHoliday();
document.querySelector(".nextBtn").addEventListener("click", e => nextHoliday() + (e.target.disabled = currentHolidayIndex === holidays.length));
</script>