Learn to Code is the New Learn to Code
it's time to learn to code; my/your first CRUD app; chatgpt live tech demo (believe me); tired of apocalyptic doomers fr no cap
The best way to support Seeking Tribe is to share it with the friend who you would tell me to get coffee with if they visited Austin:
Hi Friends,
For the past year or so I’ve oscillated between periods of intensive and often lucrative copywriting and consulting, kicking the tires on various schemes and galaxybrain ideas, and applying for jobs.
There have been victories: getting to collaborate on cool projects, significant updates to my worldview, and my first big research paper
But there have arguably been more losses: rejections, [even worse] ghostings, weeks of effort flitted away with little to show for it, and more feelings of financial insecurity than I would like to experience in the future.
This period has affirmed that I love the structure that comes from consistent work. I’m at my best when I know that my rent is going to be paid and what I need to crush it tomorrow. Having savings is necessary but it’s not sufficient. It’s creatively draining to have your potential energy spread too thin, at least without sufficient positive feedback and clear forward progress.
Now is a time for focus.
Now is the time to learn to code.
I’ve already committed (and pushed)
When you tell your software engineer friends that you want to learn to code, they will tell you that the best way to learn is through a project. And they’re right. But it’s daunting when you don’t feel like you have the fundamentals down.
The issue is that most people who focus first on the fundamentals, ie. work through a book or video tutorial, will get bored and stop along the way. I went through this process multiple times over the past few years. I even had the advantage of having learned the fundamentals of object oriented programming and data structures while in college (CSC171, introductory Comp Sci for majors, was one of the only classes that I got an A in at UR). The reality is that you don’t need anything but libraries/frameworks (other people’s code), if statements, and for loops to create a full-stack web app.
I’ve recently committed and pushed the code for the MVP of my first full stack web app.
If you’ve tried and failed to learn to code, you can iterate on this project, which I’ll spec out more below. If that’s you, don’t look at my code except as a last resort. Everyone else: feel free to hmu with constructive feedback, my code is inelegant but it works.
My first project is a Create, Read, Update, Delete (CRUD) app. The front end (Angular, HTML, CSS) displays several [hideous] pages where a user can upload an csv (comma separated value file) of users or groups, view all users or groups, or view the details of a group or user. These pages make calls to my backend (Nest) which alters the data in my local database (PostgreSQL).
It’s simply: a website that takes inputs, puts them in a database, and then can reference that data.
You could build a website where a user uploads an csv with the roster of your favorite sports team with data about the player, this page displays the roster as a table. In the table you can click on a player’s name and view their individual page. On these pages, you could add a button which allows you to mark the player as injured or uninjured. Another view could allow you to add new teams to your database (a separate table), etc.
Now that I’ve completed this first project, doing something similar would be relatively trivial. But this project took me hours and hours more than I thought it would. The most difficult parts had little to do with writing out the formal logic of the code. That’s the fun part!
Getting to ‘git add .’: a tutorial
In this section, I’ll provide an overview of the concrete steps that were required to build this project and issues that I had to troubleshoot along the way.
The first day or two of part-time work was essentially setting up the developer environment. There are a lot of pieces to configure when you’re first getting started. It’s a great opportunity to hone your ‘google fu’—ability to search for resources that answer your questions—and your humility—by asking your developer friends for help. But yeah, this process will be frustrating, even demoralizing.
Install Visual Studio Code
Visual Studio Code (VSC) is an Integrated Development Environment (IDE). This is where you write your code and manipulate the structure of your project. There is a marketplace where you can install free extensions (plug-ins) which can augment your developer experience. You don’t need to think too much about this now but these tools, especially with the release of generative AI, will become pivotal as we progress as developers. I installed: NPM, Live Server, ESLint, Prettier, Code Spell Check, DotENV, Auto Close Tag, Path Intellisense.
Do not accidentally install Visual Studio instead, like I did. If you do, you will be incredibly frustrated as the graphical user interface (GUI) looks nothing like what you’re looking at online. I don’t know why this product even exists.
Install NPM
Node Package Manager (NPM) manages packages for node. Node is backend Javascript. NPM enables you to access packages of code written by elite node developers. Learning how to use NPM is vital to your ability to build more complex software. You will quickly see that a lot of contemporary development involves configuring other people’s code to effectively solve your problems.
You will interface with NPM through the Command Line Interface (CLI), ie. Terminal on Mac. If you’ve never done this before, you will want to find a tutorial page or video.
Sign-up for Github.com and install git
Github is a cloud-based Git repository. Git is an open-source version control (VC) system. Git allows you to save incremental progress on your code. Development is not a linear process. You will need to rework your solutions as you progress. You will make significant changes to your code and then realize your latest attempt to solve a problem doesn’t work.
Effective use of git will enable you to return your local codebase to a prior, working version. This will save you from having to remember all of the changes you’ve made and manually revert them to the prior state.
This becomes critical once you start working on a shared codebase with other developers. When used properly, git allows multiple developers to work on the same codebase without requiring them to manually merge changes. Good communication is still critical but git reduces the risk of you or your coworker having a meltdown after losing hours of work.
Configuring git is easier said than done. Again, you will want to find a tutorial to walk you through this and you will likely run into a few hiccups along the way. For this project you will need to understand: “git init”, “git add .”, “git commit -m ‘made my first commit’’’, ‘git push’, ‘git pull’, gitignore, etc.
You will learn git by using it!
Create your project directory
Create a folder with the name of your project, ie. ‘my-first-CRUD-app’. All of your project’s files will be held inside of here.
Install NestJS
NestJS is a framework for building efficient, scalable Node.js web applications. It enables you to easily interface with whatever database solution you choose. You will create REST API end points, which will allow you to POST, GET, PUT, DELETE, and PATCH data in your database.
Your friends may say Nest is overkill for this project. That may be true but it’s popular and enabled me to complete the requirements.
Install NestJS by following their documentation.
Create a new Nest project within your ‘my-first-CRUD-app’ directory called ‘backend’. Follow the directions in the CLI to start up the backend.
Install AngularJS
AngularJS is a structural framework for dynamic web apps. Essentially, by using Angular you can use other people’s code to add different routes/ views to your web app, ie. you can create a web app where when you navigate to the url …/view/users, it will automatically pull data from your database and display it in a table.
The more popular alternative to AngularJS is ReactJS. I haven’t used ReactJS yet but the meta skills that you develop while using either will enable you to pick up the other.
Install AngularJS by following their documentation.
Create a new Angular project using the Angular CLI within your ‘my-first-CRUD-app’ directory called ‘frontend’.
If you successfully installed it, you will be able to enter your frontend directory and type ‘ng serve -o’ to launch the Angular template. ‘-o’ will automatically open a tab with your default browser.
Time to add and make your first commit
If you configured git properly. You will have a .git file inside of your ‘my-first-CRUD-app’ directory. If it’s not there, you will need to troubleshoot.
Is it anywhere? Or do you still need to initialize it?
If it’s there, then you need to type ‘git add .’ to stage the files that we created in this pseudo-tutorial. Afterwards, you commit the files with “git commit -m ‘my first commit’”. And to push the commit to your repo on github.com, you type ‘git push’.
Now when you go to your profile on www.github.com, you should see your code!
Meta skills and the perils of tutorials
The process of writing this overview tutorial helped me to learn why these write ups tend to be so sparse. No matter how in-depth you try to explain something, there are going to be edge-cases and issues.
All developers need to practice the meta skills of programming: search, debugging, and the ability to parse documentation. Everything is always changing. If you build a project like this, you’re going to run into errors. Packages will be deprecated. The code you see in the tutorial won’t work as you expect it to, despite that tutorial being only 9 months old.
Summary of remaining tasks to create my MVP (post-config)
Choose a database
(I used PostgreSQL and PGAdmin4 as my GUI)
Configure the database with your backend
Create your .env file
Update your .gitignore to exclude .env and production files
Install and use TypeORM to help sync and manage your data, including foreign keys
Define the Data Transfer Objects (DTOs) of your backend, ie. abstractions of user, group for use in your controller
Define the Entities, ie. structure of your table, ie. use @PrimaryGeneratedColumn() to ensure your index increments as you add new users or groups
Create end points for your user, group: POST, GET, PATCH, DELETE
Create end points for user/:id and group/:id: POST, GET, PATCH, DELETE
Test these end points using Postman
Create the requisite components for each of the pages, including upload an .csv
Define the routes in your routing file and ensure your front end can handle parameterized routing, ie. …/view/user/1 and …/view/user/2 return the data for user ids 1 and 2 respectively
Create methods which successfully interact with the end points on your backend
Validate the users’ data before uploading it to the database, ie. check that the headers of the .csv match the schema of your database (you may want to implement authentication in practice)
Confirm that all of the views work as intended
Several of these bullet points may not be applicable to your project. Your CRUD app may be different enough that these points are irrelevant, you may use different frameworks, or even find a more elegant solution. But these points should give you an idea of different words you may want to search if you attempt a similar project (italicized). Knowing what to search is a non-trivial part of the battle.
Errors and debugging
Several days through building this project I woke up with a plan to work through numerous features only to lose hours searching and debugging one specific error. This was particularly demoralizing after watching [dated] videos of people with properly configured development environments complete most of these bullet points in 20-40 minutes.
It was a struggle to initially configure git and push my first commit. I used a database that didn’t properly configure with TypeORM. I accidentally published my database credentials to github after a package (or something) altered my gitignore file.
I ventured down numerous dead ends trying to follow tutorials to complete aspects of this project. I had never written Typescript before (and had little familiarity with Javascript) so at some point a tutorial project would deviate significantly from mine or I’d run into a bug and would be unable to troubleshoot it. These failed pursuits did help me to develop an architecture for my own project as I learned the relationship between modules, controllers, and services and how to structure them in my directory. I ended up taking it from the top and focusing on learning how to build the API end points, partially with the help of a Medium post.
Another significant issue stumped me when I was creating my API end points. My GET call for all of my users worked perfectly but my call to get a single user did not work. It turned out that I needed to use a different method, findOne() instead of find(), in order to return data from both of my tables, the user and the value of its assigned group.
I only figured this out with the help of my roommate Andrew who is a gentleman and a h4xx0r. His 10 years of FAANG debugging was qualitatively different than anything I had experienced before. He was telling me to google and parse documentation at a completely different level.
There are two lessons here: the skill cap in programming is immense and it’s invaluable to know when to ask for help. Once I had the correct method, writing the remaining end points took only a few minutes.
Every aspect of this project challenged me. Previous software projects that I had created were solely backend projects without a database, or a simple script to solve a fun leetcode puzzle. There were a couple days during this project where I wasn’t sure if I was going to make it. I didn’t want to ask for help. With the internet at my finger tips, it felt like I should be able to troubleshoot the issue myself. At a certain time scale, I’m sure I would have even figured out the findOne() issue but there was always the risk that one day I would close my IDE and go back to looking at marketing jobs for products I would never buy.
It’s Still Time to Learn to Code
FAANG stocks are down from their all time highs. Meta hemorrhaging employees as the Metaverse™ fails to find product-market-fit and Apple kneecaps them in the name of privacy.
Even Amazon is laying off employees, thousands of employees. While many of those employees will be in non-technical roles, there will be a significant supply of competent developers in search of work...Let alone all the new graduates from bootcamps and remote talent.
And have you seen uhhh ChatGPT?
Sounds nice. I want to believe it. But I do wonder if it’s holding back on me…would ChatGPT know that I should use the findOne method or how to structure the entities in TypeORM.
import { Entity, Column, ManyToOne, JoinColumn } from 'typeorm';
import { Group } from './group.entity';
@Entity()
export class User {
@Column()
name: string;
@Column()
lastName: string;
@ManyToOne(type => Group)
@JoinColumn({ name: 'group_id' })
group: Group;
}
@Entity()
export class Group {
@Column()
name: string;
@Column()
description: string;
}
// API end point
app.get('/users/:id', async (req, res) => {
const user = await User.findOne({
where: { id: req.params.id },
relations: ['group']
});
res.json(user);
});
[This code is from ChatGPT. I just copied it here because it was too big for the screenshot.]
If I had used that query, it would have saved me hours of troubleshooting…This is a live demo. I had not searched that before I started working on the conclusion of this piece.
But my takeaway is the same: ‘learn to prompt’ is not the new ‘learn to code’. Being able to utilize a tool like ChatGPT and its successors will become invaluable for developers and other creatives. The productivity of technical organizations, like all organizations, will [continue to] resemble a power law distribution. The performance disparity between the most effective and least effective developers within an organization may balloon beyond current measures. I expect that technical teams will still hire ‘Software Engineers’ not ‘Prompt Engineers’. However, your ability to leverage AI augmented tools to complete your tasks will be a differentiating skill.
This may in fact be the best time in history to learn to code!
You have the opportunity to leverage all of the improvements that have been made in the developer experience over the tech bull run—including YouTube, Github, etc—and new AI tools like GitHub Copilot, Stenography, and ChatGPT to become a highly effective engineer.
Until the AI begins to generate novel applications of technology itself, productize them into software that individuals buy, and negotiate all relevant legal agreements, we will need creative, high-agency humans to collaborate and leverage all tools available to solve our most pressing problems.
Even if GPT-6 automates writing software to a level that is presently incomprehensible, that’s not a good reason to not strive today. At some point, self-driving cars may operate at scale but it was poor reasoning to not practice driving in 2011. At some point, storage technology for renewables may be reliable, affordable, and exist at scale but it would be poor reasoning to make it near illegal to build new nuclear power plants in the United States and Europe.
The future is not the present, no matter how good the memes are.
No matter what future you plan for, the details of that plan are wrong. Doubt anyone who says that now is not the time to get married and have children. Doubt anyone who says that now is not the time to learn to code. We’re alive, our time is now.
Your Friend,
Grant
I am currently in interview and application processes to secure a full-time internship/entry-level backend developer role at a remote or Austin-based company. I’m eager to augment my programming and debugging skills, leverage github copilot and chatgpt, and learn how software is built inside of technical organizations. If you have any advice as I continue to develop this new skill set and work to secure an opportunity, it would be greatly appreciated.