Home > Back-end >  Why is "onclick" only working once and fails to update?
Why is "onclick" only working once and fails to update?

Time:07-05

I am trying to understand why this onclick button is only working once. Basically I am testing to see if the "heart" or "wishlist" button is clicked on. When clicked, console.log the name of the product so I can confirm it. But it only picks up the first product. When I click the wishlist button on the second product. It gives this error "Uncaught SyntaxError: Invalid or unexpected token (at products:1:10)" When I go to that line it just show ''

I have also tried using a

const wishlistBtn = document.querySelector('.wishlistBtn');
wishlistBtn.addEventListener('click', (product_name) => { console.log(product_name) })

But it just returns that the property is null. I'm wondering if the reason is because of the innerHTML I am including all of this in.

Javascript:

const getProducts = () => {
    return fetch('/get-products', {
        method: 'POST',
        headers: new Headers({'Content-Type':'application/json'}),
        body: JSON.stringify({})
    })
    .then(res => res.json())
    .then(data => {
        createProductCards(data);
    })
}
var wishlist = (product_name) => {
    console.log(product_name);
}


const createProductCards = (data) => {
    let parent = document.querySelector('.container');
    let start = '<div >';
    let middle = '';
    let end = '</div>';

    for(let i = 0; i < data.length; i  ){
        if(data[i].id != decodeURI(location.pathname.split('/').pop()) && !data[i].draft){
            middle  = `
            <div >
                <div >
                    ${data[i].discount === '0' ? ``:`
                        <span >${data[i].discount}% off</span>
                    `}
                    <img src="${data[i].images[0]}"  alt="">
                    <button  onclick="wishlist('${data[i].name}')"><i ></i></button>
                </div>
                <div >
                    <h6 ><a href="/products/${data[i].id}">${data[i].name}</a></h6>

                    ${data[i].discount === '0' ? `<span >$${data[i].totalPrice}</span>`:`
                        <span >$${data[i].totalPrice}</span>
                        <span >$${data[i].actualPrice}</span>
                    `}
                </div>
            </div>
            `;
        }
    }
    parent.innerHTML = start   middle   end;
}

getProducts();

CodePudding user response:

document.querySelector only returns the first instance of the selector. So the first wish list button on your page is the only one that gets a listener attached.

If you're coming from JQuery, this is a nuanced difference. To add the event listener to every .wishlistBtn you could do something like:

const wishlistBtns = document.querySelectorAll('.wishlistBtn');
[...wishlistBtns].forEach(wishListButton => wishListButton.addEventListener('click', (product_name) => { console.log(product_name) })

There are two differences:

  1. The use of querySelectorAll returns a NodeList of all of the elements that match the .wishlistBtn selector.
  2. Iterate over the NodeList and add an event listener to each individual node. Unfortunately NodeList isn't exactly an array so [...wishlistButtons] is a quick and dirty way to convert it to an array using the relatively new spread operator ...

CodePudding user response:

document.querySelector works only on the first matched element. You may need to use document.querySelectorAll & attach event after the for loop has completely finished it's execution

const wishlistBtn = document.querySelectorAll('.wishlistBtn').forEach((item) => {
  item.addEventListener('click', getProductName)
})

function getProductName(product_name) {

  console.log(product_name)
})

Here is an example

document.querySelectorAll('.test').forEach(item => {
  item.addEventListener('click', getButtonValue)

})

function getButtonValue(elem) {
  console.log(elem.target.innerHTML)

}
<button >1</button>
<button >2</button>
<button >3</button>
<button >4</button>
<button >5</button>
<button >6</button>

  • Related