Bug Hunt: Part 1

Debugging is one of those skills that is commonly not taught as a skill, but described as one. Schools don’t (necessarily) offer a course in debugging and it’s not taught as a unit in a curriculum. It’s sprinkled in between learning several basic skills, sometimes included as a single exercise when learning an operation syntax, where the student is given some code written incorrectly and told to find where the problem is and fix it. This isn’t a bad thing exactly. Debugging is a necessary skill but also a frame of mind that involves patience, curiosity, and an ability to accept things not working.

Debugging can involve removing errors but also doesn’t have to. Sometimes it involves restructuring the program because it doesn’t behave the way you intended it to and the way you thought it would, until you ran into a problem. It’s the practice of making your code behave the way you intended it to, and that can cover quite a number of bases.

The briefest of them are syntax and output errors. Syntax errors are easy to fix, but can be hard to spot. In hundreds, thousands of lines of code across many different files, where did you miss out the semi-colon, the backslash, the parentheses? The error doesn’t always tell you.

The easiest way to track it down is to save and test early, test often. This is where version control comes in; a lot can be said of version control but for the purposes of this discussion version control means we can work on one small part of our application at a time, and that narrows down the potential errors from thousands of lines of code to hundreds. And once you’ve narrowed the scope of what you’re working on, you can introduce some test code.

An example of test code in JavaScript

This block of test code, which I have liberally sprinkled in my Project SEEDs application in development, tests two things. It should show the phrase “Mr. Hammond, the phones are working.” on whatever component or page I have loaded, and it should log the same phrase to the console whenever a component including this function is loaded. If I see it, I know that the component loaded correctly even if the output is null or is otherwise not what I expected. If I don’t, I know the component isn’t loading.

That gives me two possibilities for where the error is located: either in the section of code that calls the component, or the component section itself is giving me the wrong output. Hopefully both of these sections of code are short enough that I can look through them and take it line by line, testing each, first noting down how it should work in comments and then if it doesn’t work as expected, noting down how it does behave. I also try to note the input given/output expected while I’m debugging, to keep it straight and to remind myself if I need to take a break.

An example of a piece of JavaScript that adds a button to a div

Recently I was adding a button to the div (podCard) that the above code writes to. I created the variable and element, gave it some inner HTML, added the click event listener and wrote out the function it called, and appended it to the div. It appeared on the div, but it didn’t perform the function when clicked. Nor, when I tested it as above, did it log anything to the console. By doing this I knew that the problem was most likely in the function call, for whatever reason, especially as when I put the whole function into the event listener it worked properly. And I could have left it like that, but the code was cleaner when abstracted out. So what was going wrong with the function call? We won’t discuss how long it took me to realize that I’d forgotten to append the parentheses that make it a function call. (About twenty minutes.)

A simple syntax error, but all told it took me a good thirty minutes to track down, including those twenty minutes it took me just to realize that I hadn’t typed the function call correctly. And yet because the whole thing worked as directed, i.e. the event listener listened and obeyed the commands when clicked and the component loaded correctly, I didn’t have an error message to point me to line 113 and say “this is not a correct function call.” Sometimes you have to narrow it down by trial and observation.

An example of a piece of JavaScript that creates a button to render a number of items

Output errors, when your code isn’t returning the result you expected and needed for it to work, often happen because of syntax errors but not always. In the example code above, I put in the event listener what I thought was the correct function call to render all the seedling pods. I clicked the Render All Pods button, and it rendered nothing. With some trial and observation as I’ve described, I realized that the renderPods function takes an argument: the fetch data. The fetch function, on the other hand, automatically calls the render function with the fetch data at the end of the chain on the fetch request. I put in the fetchPods function instead, and it worked … well, mostly properly. Again, we have an example of the code doing exactly what you told it to do, even though it might not be quite what you wanted. This time I knew why, though, and I left myself a note for another day’s work.

Trial and error, more broadly described as trial and observation, is one of the two main underpinnings of debugging code. Whether you use a debugger or endless print statements, you’ll need to repeat your operation several times to figure out where it’s going wrong and in what way, and how best to fix it. And because of this you will also need a generous helping of patience and a healthy sense of self-awareness. Sometimes the problem isn’t only with the code, it’s the fact that you’ve been working on the application for six hours straight and you need a break, a drink of water, a meal, a nap, or some combination of those.

When I began turning towards web development as a career rather than a hobby, my mother reminded me at the outset to remember to step away from the keyboard every so often. Get a snack, go outside for a walk, take a few deep breaths. Regardless of what tools or procedures you use to debug your code, it always helps to first clear the bugs out of your biological systems and approach your work with a clear and well-fueled mind.

Wires and Lights

Over sixty years ago a man began a speech with “This just might do nobody any good.” and in a way he was right.

Not that pointing out the things Edward R Murrow pointed out in his speech, now famously known as the ‘Wires and Lights Speech’, did anyone harm. He pointed out a great many things about the then-new industry of television that needed addressing. He drew attention to several things that were wrong, that needed review, that would be better if done in a different way or that could be cause for consternation. He explained why he was concerned, and what direction he thought the television industry was taking, as opposed to what direction he felt it should take, and why that should be as well. Murrow was long dead by the time I was even born, let alone had heard of this speech or its importance, but it is still important today. (And it seems I’m not the only one who thinks so.)

I’ve been thinking about this speech a lot lately. Primarily because I’m looking for my first job in web development, I’m directing my career in the field, and I get to have my first shot at what that means. What goals do I want to achieve, other than of course the goal of paying my bills with a little extra for fun? I feel like I barely thought about it at all when I was first asked the question: I want to do environmental work, I want to work in ed-tech, I want to work in accessibility and make the internet safer and better and available to all. I was just old enough that I had some years of living in a world without internet before the World Wide Web came into being even in its first, very limited incarnation. So it seemed miraculous to me when we were able to reach across the world and learn new things, communicate with people we would have a hard time reaching before, or even knowing of their existence in more than an abstract fashion. Obviously Ireland or Russia or Brazil has universities and professors who teach at them, but with the World Wide Web a girl could find that university’s site and email those professors and ask, what do we know about ancient kings? This language? That traditional dress?

I still feel that way about the internet, even though it’s gotten quite a bit more dangerous in the years since. In many ways and along many axes (emotional, mental, even physical) the dangers on the internet have multiplied exponentially. But as we develop new technology and new software to pair with it the benefits of the internet have also grown. And along with both, the weight of our responsibility as those who are the architects of the modern web.

I’m still fumbling around the edges of what I think my responsibility is, as someone who can code. To make my web pages as accessible as possible, definitely, and I’m expanding on the knowledge of the code for that every day. Other aspects of accessibility, lean coding and designing cleanly but without unnecessary animation or components, I already have ingrained in me from the era of 28.8k modems. It can be difficult, I think, when one knows how to code and bend portions of the internet in the general direction of one’s will, to remember that not everyone has a fiber connection and a fast computer. Not everyone has a computer at home, or an internet connection. And if I’m going to code something that I want to reach even people with limited or no computer ability, if I can imagine someone might have to go to a library to use my website, I have to keep that in mind. And what else is my responsibility? To be careful with my language? To put nothing out there that doesn’t have some use? What defines ‘use’? Should the internet move towards being primarily functional and educational, and how much room do we reserve for frivolity? Who defines frivolity? Who decides what is worthy of a strong presence on the internet, and what can be left to bitrot?

I don’t have any of these answers. I know they are questions with increasing urgency, especially with the advance of blockchain technology and cryptocurrency. There are deep environmental and ethical concerns around this field, and arguments have been made that while blockchain technology and the so-called Web3 may have uses they have not yet proven that these uses cannot be better and more safely served with other, existing tech. And this is a debate that I feel we will have again and again, as innovations iterate and grow our idea of the web as it stands now into something new. It’s not done growing. It may have only reached its angry adolescence.

“This just might do nobody any good,” I mutter, typing these words into a blog entry. This is a debate we will have again and again, those of us who care and want to be intentional in our actions building the modern web. Many more of us will shrug and walk away, because we don’t care. We’re in this to move fast and break things, to develop, to find out what we can do next. And there’s something to be said for being unrestrained in one’s curiosity. But for me, personally, it must always be tempered by an effort to do no harm. I want to bring the wonderful feeling of having the boundaries of one’s world suddenly expanded beyond belief to everyone. And it’s up to them whether or not to use it; I just want everyone to have the opportunity, in safety.

React: Code Challenge Practice

It will come as a shock to absolutely no one that I struggle with live coding challenges. Many people struggle with doing work when they are being watched, and there are a number of scientific theories and descriptors as to why. It took me a couple of live coding challenges to realize what was going on but once I did the answer was mercifully simple: practice. Practice until I achieve a level of reflexive fluency.

With human languages, spoken languages such as Japanese or Italian, I would have a chapter in a textbook to study. I would have phrases and vocabulary to memorize and use in sentences, and I might find an environment where I could listen and repeat them in a conversational manner. I might even seek out a partner to practice with. Computer languages aren’t taught in the same established textbook format as spoken languages, but there is still a vocabulary of built-in methods one can learn, and a syntax, and a set of basic sentences beginning with a “Hello World!” function. So when I had trouble with my React code challenge, I set up my practice environment where I could repeat the basic React phrases, and I started repeating.

A class “ClickyButton” and its constructor method

One of the first things I had trouble with in the React live-code challenge was remembering that state exists. So, creating components that used and altered state was the first thing I needed to do. In this case, making a button that shows how many clicks I’ve made. Overall I wrote between 10 and 15 little React files that used and altered state, but ClickyButton was the first one.

An event handler function called handleClick including an if/then/else block.

After setting state, I had to make an event handler. This was more familiar from older attempts at learning and using JavaScript, but using an event handler to modify state was new, so I needed to practice it. Memorize it, as one might memorize a “Nice to meet you” or a “Where is the restaurant” in a basic dialogue exercise for a human language. For the first step, I created the incrementor and then used setState to update the state.

And then, to make it a little more complex and decorative, I added an if/then/else block. This was both to add a bit of complexity to the component and to remind myself of the format of an if/then/else block in JavaScript. I haven’t done as much JavaScript over the years as I have done CSS and HTML, and I took better to Ruby in bootcamp, so a little reminder couldn’t hurt.

A function using the State hooks

I didn’t learn about hooks in bootcamp, but I did learn about them in CodeAcademy, so I did some practice with those too. And it would help me practice thinking of React as using state. For this exercise I had a single useState hook to change the color of a div and several buttons that, when clicked, would call that setColor function. (I also, as you see, left myself comments to explain how it would work because I knew it would take me a few minutes when I went back and looked to remember how it all hangs together.)

A return block displaying a div, a p tag, and four buttons each calling setColor to a different color.

And then the second part of hook practice: using the setColor function. Each button changes the color in the div according to the divStyle assignment in the previous graphic, as explained above.

The constructor method for a react component called Oracle.

Another thing I definitely wanted to practice and make instinctive was props. Similar to state, it was a concept that hadn’t yet taken hold in the back of my mind, so I made a few components that used props. In this case, I would hard-code the props into the main app component because the point (at this time) wasn’t to learn how to pass around the props, but how to pass down the props and use them in the component.

I also wanted to practice binding methods to their specific instances. I prefer using arrow functions, but it’s always good to have a few methods in your tool-belt for doing different things; in this case I used the bind for the handleClick method.

For the handler method I used a switch/case statement, because I wanted to have multiple options depending on what the props were. I declared the variable for the result at the top, and then set it to different strings for each case. Because this was a bit complex involving some modification to the main app component, I included a console-log to track my progress.

This is not, by any means, a complete list of all the aspects of React I practiced. I mixed and matched all of these code fragments to create small, simple apps that changed text, changed colors, responded to clicks. As with practicing for dialogue challenges in the various human languages I’ve studied, it helps me to keep a space, a git repository, to practice the basic “phrases” of React and increase my fluency in the framework so that when my next code challenge appears, it comes instinctively and without more than an initial moment of freeze.