I am creating a project that when I click a certain category card I get the id of that category and redirect to movies screen.
I am aware that the row.eventlistener() in index.js it will be executed before the elements are rendered and that is why it does not pick the id. How should I add the event listener to each newly rendered item before adding it to the container so that I can get the id for each category card.
index.js
async function getCategories() {
let url = 'http://localhost:8080/movieCategories';
try {
let res = await fetch(url);
return await res.json();
} catch (error) {
console.log(error);
}
}
async function renderCategories() {
let categories = await getCategories();
let html = '';
categories.forEach(category => {
let htmlSegment = `
<div id=${category.id}>
<img src="./assets/images/sci-fi.jpg" alt="" >
<div >${category.name}</div>
</div>
`;
html = htmlSegment;
});
let container = document.querySelector('.category-grid');
container.innerHTML = html;
}
renderCategories();
document.querySelectorAll('div.category-card').forEach(row=>{
row.addEventListener('click',event=>{
console.log('Category clicked', event.currentTarget.id)
window.location= 'movies.html?categoryId=' event.currentTarget.id;
});
});
index.html
<section >
<h2 >Category</h2>
<div >
</div>
</section>
CodePudding user response:
You could also just add the event on the div itself directly when you create it and pass the id or whatever you want.
<div id=${category.id} onclick="onCatClick(${category.id})">
After this, you can move your logic inside a top level onCatClick
function.
function onCatClick(id) {
console.log('Category clicked', id)
window.location= 'movies.html?categoryId=' id;
}
This is if your styling/layout doesn't allow you to use an anchor element. Otherwise, you could simply replace the div with an anchor element:
<a href="movies.html?categoryId=${id}"></a>
CodePudding user response:
You are not awaiting the call to renderCategories
, move your event listener logic inside the renderCategories
method OR You could use an immediately invoked async function expression or IIAFE for short, more about this here immediately-invoked-async-function-expression:
(async () => {
await renderCategories();
document.querySelectorAll('div.category-card').forEach(row => {
row.addEventListener('click', event => {
console.log('Category clicked', event.currentTarget.id)
window.location= 'movies.html?categoryId=' event.currentTarget.id;
});
});
})();
CodePudding user response:
try:
async function getCategories() {
let url = 'http://localhost:8080/movieCategories';
try {
let res = await fetch(url);
return await res.json();
} catch (error) {
console.log(error);
}
}
async function renderCategories() {
let categories = await getCategories();
let html = '';
categories.forEach(category => {
let htmlSegment = `
<div id=${category.id}>
<img src="./assets/images/sci-fi.jpg" alt="" >
<div >${category.name}</div>
</div>
`;
html = htmlSegment;
});
let container = document.querySelector('.category-grid');
container.innerHTML = html;
}
//es8
await renderCategories();
// fix timeout async render element
setTimeout(() => {
document.querySelectorAll('div.category-card').forEach(row=>{
row.addEventListener('click',event=>{
console.log('Category clicked', event.currentTarget.id)
window.location= 'movies.html?categoryId=' event.currentTarget.id;
});
})
});