DEV Community

Cover image for Bugs, Errors, and Lessons: A Beginner's Debugging Experience
Andrew Ezeani
Andrew Ezeani

Posted on • Originally published at Medium

Bugs, Errors, and Lessons: A Beginner's Debugging Experience

When I began my career as a frontend developer, dealing with bugs and errors during the development of my personal projects was my greatest fear. The most daunting were those elusive bugs that do not throw any error messages, leaving me puzzled and reinforcing my imposter syndrome. I found that this was a common feeling among new developers when I spoke with others.
However, I soon realized that dreading these bugs will stunt my growth as a developer and will not make the bugs disappear. Instead, I overcame my fear by seeing these bugs as opportunities to learn and improve my skills. In this article I will share some bugs I encountered, how I successfully debugged them, and the invaluable lessons I learned throughout the process.

CSS Styling Issue

After completing my HTML and CSS lessons on Sololearn, I felt confident enough to tackle a simple project. A friend suggested Frontend Mentor, a platform that takes care of the design and allows you to focus on building projects. I registered and chose a simple QR code card component project for beginners. I downloaded the necessary file, created a new project folder, and opened it in VS Code. I started by writing the HTML markup and then moved on to the CSS styles. That was when I encountered my first bug - the browser was not updating the CSS styles I had written.
To debug the problem, I initially waited for a couple of minutes, assuming that my slow computer was responsible for the delay in the browser updates. But, even after waiting for some time, the changes were still not reflected in the browser. I then checked if I had used the correct selectors and scanned for any typographical errors in my code, but everything seemed fine.
To troubleshoot further, I changed the background colour property of the body element to red, saved the changes, and checked the browser again. There was still no change. I confirmed that the body tag was present by looking through the HTML document. This left me puzzled. I had correctly used the body tag as a selector in the CSS style sheet yet the browser did not reflect the styles. What could be the problem? I asked myself. Was CSS experiencing downtime? I pondered.
I realized the bug was not caused by a CSS downtime when to my surprise, the background colour changed to blue when I changed the background colour property of the body tag to blue using inline CSS. This piqued my interest, I converted the CSS style from an inline to an internal style and this time I opted for a purple background colour. Once again, the background colour changed to purple.
Feeling frustrated, I took a break from the project. While resting, I realized I had not checked if I linked my external CSS style sheet to the HTML document. I quickly booted up my computer, opened VS Code, and inspected the HTML document. To my surprise, I discovered I did not link the CSS style sheet to the HTML document.
Eager to rectify my mistake, I looked through my notebook for the syntax for linking a CSS style sheet to an HTML document. I added the code to the HTML document, saved it, and eagerly checked my browser. However, the background colour remained purple instead of the expected red from the external style sheet. I became confused for a moment, and I almost resumed my break. Then I realized, I had forgotten to remove the internal CSS styles I had previously written. Without hesitation, I immediately removed the internal CSS from the HTML document. The background colour of the webpage finally changed to red in the browser. This moment was particularly fulfilling for me, as it marked the resolution of my first bug without external help.
This experience taught me the importance of double-checking if the code generated using VS Code Emmet or any other shorthand extensions produces the code I intended. Here, I used VS Code Emmet to generate the boilerplate code for the HTML document and mistakenly assumed that it also linked my CSS style sheet to the HTML document. As a result, verifying if the CSS style sheet is linked to the HTML document was not the first step I took, leading to this oversight.

Inaccessible DOM elements

I was working on the FAQ section of a project from Frontend Mentor when I encountered another bug that puzzled me. The JavaScript code responsible for the FAQ functionality seemed perfect, but when I clicked on the button meant to expand the question panel to reveal the answer there was no response.
To troubleshoot this issue, I carefully checked my code for typographical errors, but I couldn't find any. I also verified that the CSS selectors used to target the DOM elements in the JavaScript file matched those in the HTML markup.
To gain more insight, I commented out the code within the event-listener function and logged a message to the browser when the button is clicked. However, when I clicked the button and checked the browser console, there was no message. I tried isolating the problem by verifying if the other sections of the website were responding to interactivity. After a quick examination, it became apparent that the issue was specific to the FAQ section. This discovery left me puzzled.
To be honest, finding the solution to this bug was a coincidence. As I carefully reviewed my HTML document, I realized I had placed the script tag below other sections but above the FAQ section. Remembering what I had consistently done in previous projects, I moved the script tag to the bottom of the file, just above the closing body tag and then saved the file. I then restarted my live server. On clicking the button after the page has loaded, I found to my surprise; the message logged to the console.
At first, I thought the bug was from the live server extension I was using because it was only after the live server extension had been restarted did the message get logged to the console. But then I remembered, that I had also changed the location of the script tag. In order to confirm where the bug originated from, I moved the script tag back to its previous location and then I restarted the live server extension. When I clicked on the button after the page has loaded, there was no message logged to the console. I then moved the script tag to the previous location where clicking on the button logged the message to the console but this time, I did not restart the live server. Upon clicking the button once again, the message was now logged to the console. That was when I realized that the position of the script tag on the HTML document caused the bug and not the live server extension.
By resolving this bug, I gained valuable knowledge regarding the importance of script tag placement. Script tags are typically positioned below all HTML elements within the body tag or in the head tag with the defer attribute if the order of execution is important or an async attribute if it isn't. This ensures sequential page loading, allowing the JavaScript code to access the fully created DOM elements. The initial placement of the script tag before the FAQ section hindered my ability to interact with the DOM elements because the JavaScript file is loaded and executed before the FAQ section DOM elements are created.

Unexpected Behavior in Product Gallery Navigation

I was working on the product gallery page for this project when I encountered unexpected behaviour in the gallery section. In desktop view, clicking on the main product image opens an overlay with a product gallery, which was functioning as intended. When the next button or previous button is clicked, both the main image in the overlay gallery and the background gallery were supposed to change simultaneously. This also worked as expected. However, I noticed that when I clicked on the next button and then clicked on the previous arrow, the displayed image is the next image in the array instead of the previous image. But subsequent clicks of the previous button exhibited the expected behaviour. Similarly, when I clicked on the previous button and then clicked on the next button, the displayed image is the previous image in the array instead of the next image. However, subsequent clicks of the next button produced the expected behaviour. You can see a preview of this behaviour below:

A gif showing the unexpected behaviour in the product gallery

To fix this bug, I followed my debugging routine. First, I checked for any typographical errors in the code but found none. Then, I examined the functions responsible for handling the behaviour when either the next arrow or previous arrow was clicked, searching for any errors. During this examination, I noticed that both of the functions handle state updates. So I decided to take a break and learn more about the useState hook in React.
I started by watching YouTube videos, but I found that the information presented was already familiar to me. Therefore, I turned to Google and looked for articles specifically about the useState hook in React. Personally, I preferred articles when learning programming concepts when I can't find a good video tutorial to reading the official documentation. I normally find official documentation to be less engaging, clear or just written with an assumed minimum technical knowledge. After reading a few articles and not discovering anything new or different from what I already knew about the useState hook, I finally resorted to reading the official documentation.
While reading the useState hook section of the official React documentation, I found the reason for the bug. It turned out that I was setting a new value for the state while simultaneously trying to access that new value. In both the showNextImage and the showPreviousImage functions, I was updating two states simultaneously, where the value of productHeroImage depended on obtaining the updated value of index to work properly. The code snippet below, taken from theProductImageCarousel.jsx file, highlights the issue:

import "../styles/product-image-carousel.css";
import arrowIcon from "../assets/icon-next.svg";
import useAppContext from "../hooks/useAppContext";

function ProductImageCarousel() {
  const {
    setIndex,
    index,
    productImages,
    productHeroImage,
    setProductHeroImage
  } = useAppContext();

  const showNextImage = () => {
    setIndex((prevIndex) => prevIndex + 1);
    setProductHeroImage(productImages[index].img);
  };

  const showPreviousImage = () => {
    setIndex((prevIndex) => prevIndex - 1);
    setProductHeroImage(productImages[index].img);
  };

  return (
    <div className="hero-image-container">
      <div className="carousel-control-container">
        <button onClick={showPreviousImage}>
          <img src={arrowIcon} alt="" className="arrow prev" />
        </button>
        <button onClick={showNextImage}>
          <img src={arrowIcon} alt="" className="arrow next" />
        </button>
      </div>
      <img src={productHeroImage} alt="" />
    </div>
  );
};

export default ProductImageCarousel;
Enter fullscreen mode Exit fullscreen mode

Based on my understanding of how the useState hook worked, I thought that since the state would be updated before re-rendering, the setProductHeroImage state updater function would have access to the updated index value just before the re-rendering occurred. Subsequently, it would update its own value, causing a re-render. In this scenario, react would re-render twice because I changed the state in the function twice. However, upon reading the official React documentation, I learned that React batches state updates and does not immediately re-render when it encounters multiple state changes within a function. Instead, it runs all the code in the function call, updates the state changes, and then re-renders the component and its children. After improving my knowledge of how React handles state updates, I removed the unnecessary productHeroImage state from the context of my app and instead I displayed the correct image by making sure that the image src is the same as the image path at the current value of index in the productImages array.

import "../styles/product-image-carousel.css";
import arrowIcon from "../assets/icon-next.svg";
import useAppContext from "../hooks/useAppContext";

function ProductImageCarousel(){
  const { setIndex, index, productImages } = useAppContext();

  return (
    <div className="hero-image-container">
      <div className="carousel-control-container">
        <button onClick={() => setIndex((prevIndex) => prevIndex - 1)}>
          <img src={arrowIcon} alt="" className="arrow prev" />
        </button>
        <button onClick={() => setIndex((prevIndex) => prevIndex + 1)}>
          <img src={arrowIcon} alt="" className="arrow next" />
        </button>
      </div>
      <img src={productImages[index].img} alt="" />
    </picture>
  );
};

export default ProductImageCarousel;
Enter fullscreen mode Exit fullscreen mode

The product gallery is now functioning as expected.

A gif showing a functional product gallery app

This experience taught me the significance of reading documentation. I have learnt to accept the fact that, although I enjoy learning new programming concepts via videos and articles, they sometimes neglect or briefly explain important information that good documentation provides in detail. I now always refer to documentation whenever I need further insights on any programming concept implementation. The React docs, in particular, have captured my attention with their clarity and aesthetically pleasing design, making them my go-to resource.

Conclusion

The turning point in my learning journey came when I embraced bugs as learning opportunities instead of something to dread. In this article, I shared my experiences of encountering and fixing various bugs, each contributing to my growth as a developer.
Now, I see error messages as helpful guides, that lead me to the source of my problem, rather than signboards announcing that I am an imposter. Having a change of mindset regarding bugs has made writing code more interesting; the satisfaction of fixing each bug serves as a dopamine boost, fueling my passion for development.
If you feel like an imposter when you encounter bugs, don't be discouraged. It's part of the learning process. For every bug you fix, your skills improve and your confidence is boosted. As you continue on your coding journey, remember that continuous learning and practice are essential components for your growth as a developer.

Top comments (0)