Thursday, 9 January 2025

Spot The Bug: Class Action!

Time for more Spot The Bug, fellow geeks! Today I'm going to detail a bug I introduced while working on a shopping cart application that was written by someone else a while back.

Prepare to be
squashed, bugs!

Since the code base is pretty large, I'm not going to paste everything here, just enough that you get the idea. So this was the product page where the Add To Cart button was. And this was perfectly OK.
But if this was a "basic" product, I had to insert a button that would take me to the "premium" product. So I wrote some jQuery code that inserted a button which would direct the user to the "premium" version. I used the same class, atsc_button, as that of the Add To Cart button so that the styling would be consistent.
if ($(location).attr('href').indexOf('basic-') != -1) {
    var button = $("<button>PREMIUM</button>");
    var newUrl = $(location).attr('href').replace('basic-', 'premium-');
    $('.desc').append(button);
    button.addClass('atsc_button');
    button.click(()=>{$(location).attr('href', newUrl); });
}

This was the result, visually.

What Went Wrong

Unfortunately, when I clicked on this new button, now it would attempt to add the current product to the cart! And then go to the "Premium" URL.

I knew this because of the error alert. Apparently the application was trying to send a null product.

Why It Went Wrong

Upon further investigation, I found this piece of code in the code base, linking the atsc_button class to a function that seemed to be adding the product to the cart.
$('.atsc_button').click((e)=> { AddToCart(e.currentTarget.dataset['id']); });

function AddToCart(id) {
    if (!id) alert("Error; product not found.");

The id of the product was determined by reading the data-id attribute of the button that had been clicked. Since the new button didn't have such an id, it triggered an error.

How I Fixed It

I went to the CSS and found the styling, then replicated it for the gtp_button class....
.atsc_button, .gtp_button {
    width: 15em;
    height: 4em;
    padding: 1.5em;
    border-radius: 5px;
    font-weight: bold;
    background-color: rgb(155, 155, 155);
    color: rgb(255, 0, 0); border: 0px;
}

And changed the class name of the button I added.
if ($(location).attr('href').indexOf('basic-') != -1) {
    var button = $("<button>PREMIUM</button>");
    var newUrl = $(location).attr('href').replace('basic-', 'premium-');
    $('.desc').append(button);
    button.addClass('gtp_button');
    button.click(()=>{$(location).attr('href', newUrl); });
}

After these changes, the button redirected to the "Premium" page as intended and there was no further drama.

Also, apparently "atsc" stood for "Add To Shopping Cart" (go figure, huh?) and now "gtp" stands for "Go To Premium". 

Moral of the Story

One gotcha of jQuery, indeed, JavaScript as a whole, is that while CSS classes should be used for styling, often they can also be used for functionality. In this case, it was both.

Possibly a better way would have been to separate the styling from the functionality, so that the look and feel could then have been reused. My way of fixing the problem wasn't great either, for obvious reasons, though it served just fine and hopefully I never have to go back to this God-awful code again.

Orange you glad we fixed this?
T___T

No comments:

Post a Comment