Toggling class does not remove element from nodelist

Hello, campers. For a movie-seat selection app, I am attempting to update the number of tickets(seats) selected and the total dollar amount ( both appearing in HTML span tags near bottom of page). I’ve added a click event listener that toggles a class of ‘selected’ on and off any divs with the ‘seat’ class, representing the individual seats you see on the page. Some are defaulted to occupied (defaulted to white color), and any unoccupied seats you select will turn blue, just as expected.

FCCQuestion

The total seats and price also accumulate just as expected, with the total price and seat count at the bottom of the page increasing for every seat element I click to add the ‘selected’ class. I intend to add all seats with ‘selected’ class to a nodelist, named selectedSeats, using a querySelector.

I chose to console.log my nodelist to troubleshoot and view the list as I toggle each seat on and off.

When I begin to toggle off any selected seats by clicking them a second time, I’m noticing that the count and total are no longer accurate to the number of selected seats remaining and the list length is longer than expected. Despite the list being created to include all elements with .selected (showing as div.seat.selected), I see after toggling off that it is now including at least one element of div.seat.

FCCQ2

The list is represented in my event listener code as:

let selectedSeats = document.querySelectorAll('.seat.selected')

…so I am not sure why the list would still include elements that have the .selected class removed.

Here is the link to my codepen. If anyone can shed some light on my issue, I’d truly appreciate it:

https://codepen.io/KODEJIMA/pen/NWpgBVN

Hello,
I noticed that you toggle the class after the assignment

let selectedSeats = document.querySelectorAll('.seat.selected');
seat.classList.toggle('selected');

So when you click a selected seat it’s still in the document.querySelectorAll(`.seat.selected'); and after that
the class selected is removed. This statement also selects the top <div class="seat selected"></div> in <ul class="showcase"> , which means that selectedSeats already starts at a value of 1 before any seats are selected.

1 Like

Thank you for taking the time and pointing that out. I found that reversing the order of assignment and the toggle method, along with updating the querySelectorAll to be more specific by specifying the .row class ('.row .seat.selected') solved the issue. I initially included the .row class in my querySelector and was getting an incorrect number (based on the initial ordering of the list assignment and the toggle method). I guess I just don’t understand why the assignment coming before or after would matter if the assignment is all done within the same function. As you can probably tell, I’m very much a beginner.

I noticed you can click the occupied seats and they will get added to the total. Unless I’m missing something here, you probably should not allow for that (check the click target for the occupied class).


Just as an aside. Whether using the + operator in front of the data type to do implicit type coercion is a good idea or not is more a personal preference. But in the case where another operator is used that also does implicit coercion, it likely shouldn’t be used.

total.innerText = ticketPrice * +count.innerText;

The * operator does implicit type coercion already.

2 * '2'
// 4

2 * +'2'
// 4

If you do want type conversion of count.innerText I would suggest using an explicit one (or just let the * operator do it implicitly). Personally, I usually prefer explicit conversion as they are less ambiguous and signal the intent a bit clearer.

1 Like

Thanks for that valuable input, my friend. I noticed that my mathematical operation of ticketPrice * +count.innerText; was working without a parseInt() or the unary plus operator when I first started testing my version of the code. I assumed JS knew to read the string as an integer, but I was also following a tutorial to compare with my solution. The tutorial used the unary plus operator. I just didn’t want to deviate since I didn’t fully understand, and I hadn’t recalled learning about implicit/explicit coercion. I really appreciate your informing me of this, because I was definitely wondering about it.

I also changed the .seat selection in my querySelector to .seat:not(.occupied) to avoid that issue you mentioned on the click event. I have only done this in my IDE as of now, and haven’t yet updated my codepen. Thank you again, lasjorg.

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.