Welcome! I've had a wonderful opportunity to work with some amazing people in Lambda Labs, after working hard and long at learning what I could from Lambda School's Full-Stack Web Development course.
In this post, I'll give you a semi-short rundown and some good practices that I learned that you can apply to just about any project and how to work with a team to get things off the ground and have great experiences along the way. To make it easier, I'll set up a Table of Contents, and at the bottom of each section a way you can jump back up. Easy as cake.
- Setting the Stage
- Learning your Lines
- Act 1
- Act 2
Your Organization is the key reason as to why you are developing your application, and who actually owns the application. They may have specific rules as to what you can use, how you implement what you're allowed to use, and how you go about reporting your progress to be tracked. Often there are stakeholders who have invested in the project who will want to know how you're putting things together and your progress in how it is working or if it's even working and a timeline of events and staging. Like Release Candidates or versions of the application, and what you might need (within proper reasoning) to move the project forward.
So, you're going to need specific tools to make your project. For woodworking, you'll probably use actual tools like screwdrivers, hammers, sanders, nails, and anything to put it all together. In the case for programming: We're looking at things like Packages that you'd install into the application to make it work.
In the case of this project, a lot of the decisions and tools were already established by the Organization we were working with, which I'll go over a bit later. The packages at least for the Web development side were React.js, Axios, Heroku, AWS, Okta Authentication, Express.js, Knex.js, Redux for state management, Node.js, and Node Package Manager for installation. Docker was also a choice given for local hosting of the web database for testing and virtual machine hosting.
Then there's Whimsical, which has several uses. Below, we used Whimsical as a visual guide, a breakdown of what the application roadmap would look like and how things would connect when the application is complete, the status of how it works, etc.
Trello is a big option for the flow of communication, as well as a visual guide via cards to explain what has been done, what is in the process of being done. Below is an example of a Trello board.
Also, here, and example of a Trello Card which includes links to Pull Requests hosted on GitHub and checklists on what has been done on a particular task.
GitHub was the Version Control and code storage method chosen, though your Organization might have different options.
Any good project starts off with a Plan, like what you're making, how you're making it, and the process in which that you go about doing it. This isn't exactly just for programming, and it applies to just about any project. An outline of your goals, what tools you need to accomplish said goals, and how you plan on having it presented. In this case, we're going to cover an experience I had working with a great team attempting to build off an application designed to present information for Cities.
In the case of our project, we took what goals we were given and set out to look them over in a way in which who ever might be using our application might best want to work with it by making User Stories.
As an example: As a User, I would like to save Cities to resume researching later.
So, What do I mean by a Contract? A Contract is more so a Promise, or an outline of what it is, such as a database endpoint, in which something is agreed upon by your group. As long as it's something your team can connect to, work with, and returns with the promised information, that contract will be fulfilled. These are important for the flow and communication within your team.
Your team is going to either be big or small, but no matter the size, everyone is going to have a role to keep.
My team comprised of 5 web developers including myself, 3 Data Scientists, 1 iOS developer, and our Team Project Lead.
Within that composition, our web developers were broken into 4 Front-end developers that took care of various things, 2 of which were design leads, and 1 Back-end developer, which is the responsibility that I took charge of.
Your mileage may vary, both in size and ability. Just try your best to be as patient as you can with your team, and hope they're also patient with you.
So, you've got your plan. You know what tools you're going to use. You have everything together, know your role and what part of the grand plan you're in charge and responsible for. You might be working from scratch, or be working with someone else's code (more likely the latter). What's the next step?
You're going to want to lay out what you're doing and in what order. Such as building a basic frame to hold the code you are going to implement. That could even be specific modules that you've named.
Getting a good idea of what you're doing based on your experience and research, then actually writing it out on something like a piece of paper, or in a text file separate from your project so you can refer to it is a good plan. Even if it's not active in an IDE, it helps you form a basis as to what you're building and putting together. Just like the planning stage, this is where you break each individual thing out like making a map and gets it moving in your brain.
Break each problem down. First start with a main goal, an outline of what it is that you need in order to reach that goal, and then write out cases, from most common to least common (or edge cases). This can take a bit of time if you've never done this before, but it really lays out what it is you're going to do and how to get it going.
Even in programming: Measure twice, cut once. This ideology helps reduce errors, and builds better applications. If you have to research something, getting as much information about something before you start reduces problems and helps you fix the bugs when they do turn up.
You're going to have basically 3 key environments: Development, Production, and Testing.
Development is where you write your code out and work most of the bugs you can find right away.
Production is what is launched, or known as your deliverable. Your project in a released state.
Testing is exactly what's on the box. This is what you run when you're doing automated testing, which is code that acts like the user.
Alright, you've got yourself a framework, you know what you're using, you're ready to get started installing your stuff.
You've got your IDE setup, you're getting your packages installed that have been decided on with your team as to what you're using. Awesome. This is probably going to be a lengthy part of the project, because you have to make sure that your packages install with the right version to get everything to work, and each package has it's dependent packages installed.
Well, Let's go back to that project I was talking about. One of the biggest problems I had was getting Docker to function correctly. I had a myriad of different issues, starting with the fact that Docker being a Virtual Machine emulator, I had VMWare (another Virtual Machine Emulator) installed with Vagrant. Docker then decided that that was the moment in which My PC (running windows) would become unstable. Frequent false starts, wouldn't boot up into windows fully, I/O errors.
So, I uninstalled Vagrant and VMWare thinking that would fix the issue.
Okay, So I uninstalled Docker, let someone know that it wasn't functioning as intended, and then I was let in on something new, or at least new to me.
So, I had set up WSL2 a while ago when I was playing around with Vagrant months and months ago so I could see if I could get Ubuntu running in the background. At the time, there wasn't any actual kernels to install to get it going very well, so installing some packages were moot. What I didn't know was months later, someone wrote an official kernel and I didn't have that installed. So, I went through and checked via PowerShell that WSL2 was in fact installed (which it was), then installed the Kernel. After that, I installed Docker and Voila! Test Repo went through, and that allowed me to punch forward with a now stable machine. Awesome.
That's a curious phrase, right? Well, not really. So you're going to have to deal with a few things like Hosting. That could be AWS, or Heroku, or Elastic Beanstalk. With those kinds of things, you need the right variables to ensure that whatever it is that you're going to launch the product on is available to you: You have to gather your resources and put them where they're secure and accessible by your application, or group of applications that talk to each other. This could be environment variables, could be log-in information, could be a bunch of things.
You'll decide with your team, or your Organization will give you what you need, in order to get those things up and going in preparation. It might be that your application is already hosted. That might save you time, but being able to affect those things and connect with them is very important. Don't forget last minute.
This part is going to probably be ongoing, but it's just as important as the rest. No matter how good you are at measuring, you'll probably mis-cut at some point. That's fine. Things happen. It's how you handle it when it does happen. This is where you're going to have to keep your cool and track things down.
So, something I learned when your web application isn't exactly stable is learning how to read the errors. Some might be general, some might be explicit, and then there's tests that might run to ensure that your best practices are being generated properly.
I came across some variable errors while attempting to launch to Heroku. First, I was getting a error code 1, which is super general. I updated the information to allow a recent version of Node.js, which fixed the error, but it could have been a ton of things. Do a bit of research on the error to find a solution.
Another error one of my compatriots came across involved a module not working correctly. So, we went through and turned every import to explicit de-structuring, which isn't going to solve the problem, but what it did do was layer down to the root cause of the main error as to why it wasn't importing properly. After fixing the root error, we removed the de-structuring and it cleared up the issue and the application was running properly.
So once you get your code working, it might look like a huge mess. Refactoring is important as it helps clean up the code for readability. The easier the code is to read and to track, the better it is in case you need to get into it and especially if someone else is going to dig in themselves. Chances are someone else is going to read your code and work off what you've got there, while still doing their best to maintain what it is you wrote.
What else is cool is if you have a particular feature you want to make work better. Getting those lines down without compromising the functionality of your code will not only streamline the process, but reduce the amount of space allowing more room for more things within possible limited storage. Web pages and applications are getting beefier, and the less storage you take up and use smaller scripts to increase the load of a program/application, more likely you'll be able to not only track bugs down to a specific module instead of looking through a sea of code, but the better the readability is going to be. You'll know where things are, and how they're stored.
Also, More features != better. You want to make sure that while you're adding things to the application, the more you have things built into it, the more cluttered it can get, not only with code because you have to be aware of things like side effects such as one feature interfering with another feature, but also just the amount of options can be overwhelming to a user if it's not implemented where it's intuitive to the user. Think less like an engineer in that respect, and think like the User. Lots of options can be great, but make sure they work off of each other.
Alright. You've got your plan, your frameworks made, you've prepped for the most common bugs, you've kept everyone in the loop, you've got everything you need installed. Here comes the fun part: Code. Write it out to the best of your ability, and even do your best to go above and beyond what you've learned previously and make the most of it. That's really all there is to this part. Just pay attention to how your code displays. If you're requested to use a linter, cherish it. It'll help you out immensely, but also make sure to do your best to write it all out without having to rely on copy-pasta or autofill. Think of those things more so as suggestions, and it's more likely those suggestions might actually lead you astray, while on the occasion, they can help you (like getting those pesky imports to function properly). Toss some music on that inspires you and go deep in.
Make sure you document your Pull Requests with what you've done. You might have a template to follow via your Organization, or you might not. If you don't, Make sure you build one out so that you and your reviewers can identify what it is you're adding or editing and want to merge into the main project. It's always good to have a couple sets of eyes on something in case you miss something or it's just not working like it should. Keep the conversation going, and if you're reviewing someone else's code, do the same. Don't take it too personal and be patient with the process, and know that someone might not get to yours as quickly as you'd like. It's going to be alright. Just reiterating: Keep the conversation going.
Now you've written your code, you've debugged, you've let your team know what's up, and it's time to punch it up to the server with a working deploy. You've done it.
From there, if there's more features you need to add, you get to start the process over from planning, the framework, making sure your dependencies are set up properly, and then diving right into the code before requesting it to be pulled into the main code. Rinse and Repeat.
Documentation is super important. I can't stress this enough. When I got into my project, it was a build-on that didn't really have a lot of documentation as to what was already written, and it took a bit to explore what it was that I needed and what was or wasn't already built out. I'm not saying write out a full blown wiki, but something along the lines of informing of what else needs to be done, or what has been done, is a good idea in order to get the next person moving a lot faster into the code. Also, making sure that your pull requests have enough information to go off of is excellent. The next person that looks at your code and reviews the documentation can get what they need installed in order to get the project going and hit the ground running.
This is also good for any project, not only the ones you work on with a team. A thing to remember, though: Not everyone is going to be at the same skill level. There might be people who have a natural knack for programming, and some people might be struggling with it but are making at least a real effort to get things going. Making sure that your documentation is clear enough for both ends of the scale is not only best practice, it's the cool thing to do. I know I could do a lot better at that, and am making large strides to doing a better job at it.
So, this blog post is most definitely the first of many, and don't think I'm hanging my hat on this stand: There's going to be a lot more working with Teams, Solo projects with breakdowns on how I got them going, and a lot more. The first of many.