The Next Step

Aaron Yates
11 min readMar 7, 2021
long paved road into the distance

The Background:

So to preface this blog entry I suppose that I should start by giving a little background. Hence the title, clever right? I’m Aaron and I’m an aspiring web developer. Like a growing portion of the population, I can’t pony up thousands of dollars to enter a traditional college, I have the debt from my university as my battle scars from trying. Enter Lambda School, a young and quirky new kid to the education block. Half bootcamp and half positive developer community, their aim is to provide an education in development and related fields at a reasonable cost. Which their education was more robust that I could’ve hoped for going into it. I’ve had a good experience, and while it isn’t perfect, the curriculum is evolving and refining even as I type this.

Well as we finish up the course we have labs that simulate a real-world development environment where we’re matched with a team and are given a product to either build or polish. It gives us a nice portfolio piece, and gives us a taste with working with the same team for almost two months. So I’m here to talk about my Labs project and reflect on the experience as a whole. I was tasked with a project that already had a team that had worked on it. Four other people excluding myself were on my team and the project was called Merchant Marketplace. The application was designed to allow users to order items from retailers and other users, and have them delivered to brick and mortar locations for pick-up. The groundwork was laid by the last cohort and a lot of our technical decisions were made for us going into it. The experience of picking up an existing project and working with it was a very unique and valuable experience, and was much more challenging than I would’ve initially thought.

The Project

So for this application we were using PostgreSQL for our back-end, React for our front-end, and Node/Express as our development framework. Additionally, we also had Okta handle our authentication flow, ElephantSQL to interact with our database, and ant-design components to work with on the front-end. There were a lot of new technologies going into this project. I’ve never utilized Okta or ant-design, and I had a tentative grasp on PostgreSQL at best. There was a little anxiety about utilizing new technologies effectively, but that’s part of the fun of it. Learning something new and finding out what you can piece together from it, and as I was about to learn I had a solid team to back me up.

As with most projects I had a team of people to make things easier, and sometimes harder, on me. To protect their privacy I’ll be giving them a short introduction using a single initial and just give the broad strokes. There was B, the quiet sarcastic one that wouldn’t stop talking when he opened up to everyone. J, the winner in life that just keeps getting lucky for no real reason. D, the mature gentleman who radiates wisdom. Then there was Baldie. I never really was sure what Baldie did, but whatever he did, he did it well. I think? Finally there was myself. The stoic and reliable leader that everyone looked up to throughout the process. J and B buddied up and took the cushy back-end jobs, while D and I were saddled with the heavy lifting up front. Baldie was the designated babysitter for our group of problem children and he uh… was around. So with our technological decisions made, and our team assembled, we ventured into the thicket of the code. Where it promptly broke, and we couldn’t get it working.

The Work

So after meeting for the first time and all the awkward introductions and questions were done, we had someone share their screen and fire up the code editor to take a look at what we had going on. To which it spit out a cryptic error and then promptly told us that we weren’t cool enough to enter the club. We fiddled with it for a few hours, edited the env variables, made sure that they were all on the right ports, looked at our knex configuration. After about three hours or so with no headway we broke for the night and decided to tackle it again next time. The next day we reread the instructions and we all try different things. I tackle setting up a local instance of PostgreSQL, and everyone else split between using Docker or ElephantSQL. I waste my time for a day getting a local instance of PostgreSQL set up, just to realize that by changing the configuration file to suit my local instance, I break everyone else’s set up because ElephantSQL/Docker doesn’t play nice with it. So I let out a big sigh and do something I’m really bad at. I let go of my work and effort and I obediently get ElephantSQL set up. It isn’t worth the time and effort to try and force my own method to work, and ultimately slow down the team. I could’ve saved much more time by decisively dropping setting up a local instance earlier, or communicating with my team as to the advantages of doing it the way I wanted to. A local set up for PostgreSQL would’ve been more reliable, and while we could all work off of the same set up for ElephantSQL it also would be spotty if someone was working on the connection, and I think most developers going into it would have preferred a local set up as an option if it was configured properly. However, I decided to dig my heels in and do my own thing without communicating clearly and I lost an entire day I could’ve been doing something productive. Well, live and learn right? Wrong.

I always considered myself to be an apt communicator. I’m relatively articulate, and I can break things down into simple points to make it clear. However, I’m also used to working by myself and just implementing what I feel to be the most optimal solution. So we, as a team, agree that adding some shopping cart functionality to the application would be a fine addition. So the back-end starts working on the endpoints we would need to store our shopping cart in our database and I start implementing to logic for it while D, the other front-end developer, works on another bit of front-end logic. Everything is fine and dandy, I’m looking over the redux state flow that the previous team implemented so I know how to appropriately integrate the new functionality and ruminating over how I want to do it. I’m in my element, pouring over code and obsessing over a single problem and refining the solution in my head, and occasionally in my hand-written notes, when a thought crosses my mind. A user is going to be interacting with the cart multiple times per visit. Inherently the cart is a fairly volatile piece of information and having a back-end call for every single action that someone wants to take on their cart isn’t just suboptimal, it borderline isn’t functional. Especially since the last team implemented the item pictures weird and we’re making two external calls for every item, one for the item info and one for the item picture. So I think to myself about using a local storage set-up, do some preliminary research and let my back-end know that they shouldn’t waste their time and work on to something else, right? Nope, I’m so immersed in the problem and the research that I throw my team to the back of my mind and I really get into the guts of how I want to do the cart. Then, a day and a half later, during our next meeting I let B know that I decided to go a different way with my implementation and explained my reasons. B agreed with me at first and then got VERY quiet. After a moment he sighs and says that it’s fine. Even if I didn’t do it exactly how I needed to do it, everything’s fine, right? Well it would be, if half of our back-end team didn’t waste a good portion of their time on functionality that will never be used or see the light of day. To put it into perspective, let me post B’s table alone.

B’s table implementation
RIP shopping_cart table.

There she is, the moderately sized table that she is. There was a lot more that went into this, but even just the table alone is a testament to how much thought B put into it. We only get 3 hours a weekday to work on this project, and I blew at LEAST one of his days on just this functionality. That’s a big problem. During our Labs I just put a pin in it and realized that I messed up and moved on, but I wanted to really reflect on my short comings for this blog. I wasn’t the super coding all-star I thought I was. It’s a simple, basic, preventable mistake that costed us valuable production time. Any time I saved by being clever and knocking out the cart logic quick was more than lost in just not speaking up and sending B a quick message. I honestly think I’m an able coder. I’m obsessive enough to make sure that I know the material well, and I’ve got the fundamentals down so I can take a problem and just run with it even if I don’t know the specifics about the language or library. However, I had the chance to be decisive about how we interacted with the database and my indecision cost us a day or even two of work, and my tunnel vision had cost us another. It was a silly mistake to make, but the show must go on.

The Finish

Acknowledging one’s deficits is a difficult, but important part of growing. Dwelling on them, however, is counter-productive. I let B cry his salty tears into his pillow and I throw myself into my work. I decide that since the previous team went with a redux state flow, and all of our fetching and external logic is wrapped in it that I wanted to implement the cart in the same way. It’s less optimal than just accessing the local storage when and where I needed to, but we weren’t going to be the last team working on this project. There was going to be at least one additional team. So after weighing the pros and cons, I decided to do a slightly less optimized solution in favor of better maintainability. Keeping all of our logic in the same format, using the same rules, allows for people to wrap their heads around it faster and understand what’s going on. While if I try to do the absolute best performing code, it’s less clear right away what’s going on, and I’m barely saving any time with it.

shopping cart actions code

So I happily tap away on my keyboard, feeling good about life, and then I come to the point to where I’m ready to toss the dummy data I hard coded into the state store for the cart, and actually fetch a cart from local storage and edit it live. So when a user logs in, it grabs the right info and you’re good to go. So I pull up our log in form and… whoops. Okta handles it all with their handy little widget and obfuscates all the user code. I can’t just grab a user-name and use it as the key for our local storage. Well alright, I’ll just go to the landing page a user is automatically directed to after logging in and go from there. Which works, I’d still prefer for it to be apart of the login logic, but time is running low and I don’t have the leisure to peel apart Okta and see how it ticks. I’ve got 3 days to make sure that this is worth putting my name on. So I take a look at the tokens provided by Okta post login and see if there’s a constant that can be used as a handy-dandy local storage key. Oh, no such luck? Well alright, if you can’t solve a problem, move on and come back to it. I slap a generic key for a universal active-cart and just make sure that everything is working right.

A couple of days pass and I have all the unexpected behavior more or less worked out. You can add items to your cart from the detailed item view, edit the amount, and even remove it from your cart by putting a quantity of 0. You can also edit item quantity and remove items from the cart overview and edit multiple items at once. Feeling nice and accomplished I give myself a nice little pat on the back and let the team know that their esteemed leader has once again delivered the product with time to spare. So I commit and I’m feeling good about it, but wait… wasn’t there a problem with the login logic? Gee Wilikers Batman, we’re boned. As it is now, all profiles use the same local storage key for cart info. So all users will have access and be able to trample all over each others information. So I burn the midnight oil, work off hours, see if I can grab some kind of user information or something to identify each individual carts. I try everything my caffeine and sleep deprived mind can think of right until the last minute, but… nothing. I would’ve definitely figured something out if I had another couple of days, or maybe even one where I could not panic and actually think, but that’s not how it worked out. I had to do that thing that I’m really bad at and let it go. I slap a comment on it, point out the flaws in the logic and I commit and push it up to main.

Looking Back

I went into Labs pretty optimistic, and it could’ve gone worse. I’m not sure how exactly, but there’s probably something else that could’ve blown up. To take a second to not be hard on myself, I’m not the only one who made mistakes. I did have victories and I did assist in a meaningful way, but my mistakes are the only ones I’m responsible for. There was a lot I could’ve done better. I’m actually quite disappointed in my performance. That’s alright though. I learned a lot about some new technologies, I can set up local PostgreSQL a lot faster next time, I learned how to work with ant-design, and I got some insight in to how I can improve as a team member. I wasn’t the coding super-star I thought I was, but I’m closer to being one now than I ever have been. I also met 4 great people and had the pleasure of working with them, and I hope I have that opportunity in the future. I’m less sure now than ever that I’m ready to be thrust out into the world as a developer, but if not now, then when? Very rarely will things be optimal, and even rarer will we ever be truly prepared for the challenges ahead, I know my strong points and I was reminded about my weaknesses. Ready or not, here goes the next step, and may there be plenty more mistakes to learn from in the future.

--

--