Home > Enterprise >  Event listener not working after elements are rendered in the dom
Event listener not working after elements are rendered in the dom

Time:06-03

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;
    });
  })
});
  • Related