'How to apply styles from a JSON file using for loop?
I'll cut to the chase, I'm still a beginner with javascript and I'm having trouble correlating some data from a JSON file to specific HTML elements using a "for loop", so I can apply styles to them.
Here is my HTML:
<button onclick="yearMap(2004)">See songs</button>
<div class="yearmap-1">
<li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li><li></li>
</div>
My javascript is as follows:
async function yearMap(year) {
const api_url = 'https://opensheet.elk.sh/1oxsWP57qoaxOZFUpPmwQ-Dkagv0o87qurp92_-VKITQ/year' + year;
const response = await fetch(api_url);
const data = await response.json();
for (let i = 0; i < 52; i++) {
const { no1genre } = data[i];
document.querySelector('.yearmap-1 li:nth-child(' + i + ')').style.backgroundColor = no1genre;
console.log(i)
console.log(no1genre)
}
}
When you click the button, each <li> element is supposed to be styled(bg-color) chronologically per each instance from a data column(of hex-codes) in a JSON file. There are several lines of data and HTML elements so I thought that using a for loop with an :nth-child selector would be the best way to do this, but I keep getting the following error: Uncaught (in promise) TypeError: Cannot read properties of null (reading 'style') at yearMap
When I replace the "i" inside the nth-child selector with a number, it alters the style of the referenced <li> element just fine (with the last instance of no1genre from the JSON file).
Furthermore, the console.log(i) and console.log(no1genre) prove that each number from the loop and hex code from the JSON file can be referenced together, but I'm just not able to apply them to each <li> element. I suspect that :nth-child is not the way to go with this, but I'm not sure what else to try?
Thanks in advance for any help!
Solution 1:[1]
Instead of using nth-child which may or may not actually match an element, I would iterate the list of elements and assign values accordingly
document.querySelectorAll(".yearmap-1 li").forEach((li, i) => {
li.style.backgroundColor = data[i]?.no1genre ?? ""; // or suitable fallback
});
Solution 2:[2]
I think for your case, the best approach is to create new <li> elements in the for-loop and append them to the correct position, instead of having a fixed number of <li> elements and changing their properties.
You might want to look at createElement and appendChild.
Solution 3:[3]
You can use the eq(); function to specify the index of each li in your parent class yearmap-1 and then you can appy
Solution 4:[4]
working code
Html:
<button onclick="yearMap(2004)">See songs</button>
<div class="yearmap-1"></div>
Javascript:
async function yearMap(year) {
const api_url =
'https://opensheet.elk.sh/1oxsWP57qoaxOZFUpPmwQ-Dkagv0o87qurp92_-VKITQ/year' +
year;
const response = await fetch(api_url);
const data = await response.json();
for (let i = 0; i < 52; i++) {
const { no1genre } = data[i];
console.log(no1genre)
const li = document.createElement("li");
li.style.backgroundColor = no1genre;
document.getElementsByClassName('yearmap-1')[0].appendChild(li);
}
}
Solution 5:[5]
The problem with your code is the loop you are running. Your loop starts from 0, due to which the selector statement becomes
document.querySelector('.yearmap-1 li:nth-child('0')').style.backgroundColor = no1genre;
And since it is trying to get the 0th element with nth child selector which is not possible(As the first li element will be the first child and not the 0th child).
So either you should update your loop to start from 1 or you should use :
document.querySelectorAll('.yearmap-1 li')[i].style.backgroundColor = no1genre;
inside your for loop. document.querySelectorAll('.yearmap-1 li') will give you all li items as an array and then you can iterate over them to get your desired li element.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Phil |
| Solution 2 | cSharp |
| Solution 3 | Harinder Chouhan |
| Solution 4 | rahul sharma |
| Solution 5 |
