October 13, 2020
It’s common to feel like if we planned ahead better, had more meetings or used a different tool, that problems could be avoided altogether—but the unfortunate truth is that they will always show up.
Whether it’s a major bug in production, a never-been-done-before project, or just trying to figure out CSS grid— problems are a daily activity for developers. Once you accept this, you can work on learning how to keep them from blocking you completely and, instead, move through them faster.
While each issue is going to have its own nuances and solutions, there are ways you can build your problem-solving skills so you’re better prepared the next time you hit a wall.
Just to clear things up from the start, let’s run through a couple of wrong ways of solving problems.
Listen—we all do this, and when it’s some clever one-liner or a very specific solution, it’s not a big deal. However, when you start just randomly pasting in other people’s code and hoping something eventually works...well you aren’t really learning anything at that point. Maybe it will temporarily fix your problem, but if that code causes another issue down the road, you won’t have any idea how it works, landing you back where you are now.
Pair programming is great. Talking something out goes a long way and it can be a great idea to ask your team if anyone else has solved your problem before. However, handing it off to someone else to fix just because they are willing or have more experience will land you in the same boat as copy/pasting. The next time you hit a similar problem, you’ll just need help again and won’t have learned anything on your own. There is a better way.
The issue with both of these is you aren’t learning anything new. As we’ve already established, you will always have problems—even the most seasoned dev still googles “How do I exit the Vim editor?”.
So how do you solve a problem?
As previously stated, every issue has its own specifics, but since there are high-level commonalities in all problems, I've learned that you can use a pretty standard method when attacking an issue in your code.
Clearly break down the entire scope of the issue.
What are you starting with?
What do you want to do with it?
What does it need to be in the end?
Write it down, explain it to a duck, or write pseudo code.
Wrong: This list needs to be sorted by categories and dates.
Right: I have an array of calendar days. Each day object contains a date and an event. Each event on the day contains a user id, a category and an event caption. The list needs to be grouped into sections according to the event category and then each section needs to be sorted in ascending order by the date.
Take it a step further than “this isn’t working” and be very detailed. If you’re getting an error, what is the actual error message? Is the image off-center by 10 pixels? Is there a test that’s failing? Is a component not updating correctly?
It’s important to be able to fully explain exactly what is happening. This is more relevant if there is already a faulty solution in play, but regardless you should still clarify this part.
Wrong: The list isn’t sorted right.
Right. The list is currently being sorted in descending order based on the date the event was created and there is one single list with all the types of categories combined.
It can be hard to find the solution when you’re looking from a general view.
Tear down the whole thing as small as each part can go. Figure out the order in which the methods are being called. Make a note as to what each step physically does and what else it affects. This can help expose unintended side effects, functions you didn’t realize were being called, or steps being out of order.
Example: The list is being fetched from the date endpoint. After it is received, it is sent through a function called sortList. The list is filtered by the created_at property. Then the list is displayed on the Event page.
Console log. Use dev tools. Comment out methods. Set up breakpoints. Read the docs.
Comb through every component that you previously broke down and make sure you understand what each part is doing. How is it manipulating the date? What is it returning? Is it calling other methods? If the issue is not immediately clear, it can be incredibly helpful to comment out all the steps and then, beginning with Step 1, add them back in. At a minimum, this will narrow down your focus and let you know where things are falling apart.
It can be tempting to skip ahead and start at step 3 or even 4— but without a clear understanding of the current situation and the end goal, the process becomes convoluted and unclear.
Bonus, if you do end up needing to bring in another developer, it’s much easier for them to get up to speed with a clearly defined problem and goal.
I know what you’re thinking right now—“this is great when you have all the time in the world to solve a problem, but this just doesn’t hold up when there’s a huge issue in production and you’re scrambling to fix it”. That’s when you start throwing in random chunks of code hoping one sticks—and maybe one will eventually, but you won’t end up with a solid fix and you’ll be back in the same situation before you know it.
What you can do before that happens, however, is practice and grow your problem-solving skills when the stakes are much lower.
Next post, we’ll look at three practical ways you can do that. Until then, enjoy this cartoon called "Zeno's Progress" by monkeyuser.com.