Taking A Short Hiatus
At the start of this year, I committed to maintaining a write everyday, publish once a week schedule. That has been going well, but at the moment, I'm in a position where publishing every week just isn't realistic so rather than force it and/or beating myself up over it, I will be taking a short break. I fully expect that I will resume publishing articles again sometime in October.
Unwrap Values from a Maybe
In the previous articles in this series, we've covered the
Maybe type to gain a general understanding, and we've seen how we can construct a
Maybe with the
safe function. Applying functions to values within the context of a
Maybe means we can perform our transformations with more confidence. At some point, we’re going to need to extract our value to use it in places where our code expects a raw value. In this article we'll see how to do that after we introduce a little bit of function composition.
Create a Maybe with a safe Utility Function
In the previous article in this series, we looked at the Maybe type and how we could use it to abstract guards out of our code and into the type. We first constructed the
Maybe.Just directly, then created a very specific utility function to construct them for us. In this article, we'll create a more generic utility to understand it first and then we'll look at one that is built into the crocks library.
Understanding the Maybe Type
Imagine a scenario where invoking a function could fail if an argument passed to the function is the wrong data type (i.e. a string instead of a number),
undefined. You can guard against errors by checking your input with
typeof or checking for
undefined. This adds code and can make reading and refactoring more difficult. This sort of scenario is exactly what the
Maybe type can help us avoid. The
Maybe offers a way to encapsulate the safety that these conditionals bring without making the code too "noisy".
The Value of Remote Work
In my 21 years in tech, I have worked in several industries and bounced between working from home, and working in various types of offices. I've worked in dull beige cubicles and "cool" modern offices. I've had short commutes and commutes that had me spending almost the same amount of time in a car as an office chair. I've taken my dogs to work, had beers at my desk, played ping pong in the office and had to wear a tie every day. I've seen it all, and without a doubt, regardless of the industry, my work from home jobs have been where I've been the happiest.
Establishing a Writing and Publishing Habit
I've written off and on for ages, and it always seems to fizzle, never fully developing into a hard and fast habit. As I write this, I've been writing daily for 270 days straight. I think I've finally found the right approach for me. It may or may not work for everyone, but I wanted to share my thoughts on what is working for me now so it might benefit others.
Front End Data Caching with the AWS Amplify Cache Utility
I've worked in a lot of frontend code bases over the years and I've found that in many cases, the "state management" technique of choice turns out to primarily be an API cache which is different from UI state. When state is held in context (directly, via Redux, whatever) for use across components it is frequently just an in-memory copy of some data that has been fetched from a backend API.
Note Taking and Writing in Obsidian
I have a long history of trying various note taking techniques and tools. I've used paper notebooks, followed the bullet journal method, and used countless digital tools with varying levels of success.Writing on paper has its advantages. It forces you to slow down and capture only the most relevant information. But notebooks are limited when it comes to things like search. You can use an index like the bullet journal approach, but once you have multiple notebooks, now you need to go dig through old notebooks that contain the content you're looking for. It's also hard to create links to websites on paper 😅.
Cannot read properties of undefined error.In this article, we're going to build a handy little utility for safely accessing a property of a nested object.
Unit Tests as a Learning Tool
Unit testing and patterns like TDD are enabled by tools that create small, isolated execution contexts for your code, allow you to make assertions about data and behavior, and allow you to substitute dependencies with mocks.These capabilities are quite powerful for testing your code, as one would expect. The same collection of capabilities also creates a fantastic environment for experimenting with code. When I want to learn a new library, I will take the typical paths of reading the documents and looking through the code and then experimenting with the code. When I'm focused on language features, utilities, data structures, and the like, a toy app isn't always the easiest way to experiment. In these cases, I reach for testing tools as a learning environment.
Add File Generators to Your Project with Plop
When working in a code base we develop habits and patterns that help keep our codebase consistent. For example, we probably store new UI components in a shared folder, maybe with a specific pattern for the sub folder hierarchy. Along with the file for the component implementation itself, we'll probably add a file for component tests, and maybe a third file for some storybook stories.
Create a VSCode Snippet with Multi-Cursor Support
VSCode is a powerful editor right out of the box, but it becomes even more powerful when you customize it. A lot of VSCode customization takes the form of extensions, but in this post we're going to cover how you can add your own custom code snippets.
Jest Testing with test.each
Often, we end up creating multiple unit tests for the same unit of code to make sure it behaves as expected with varied input. This is a good practice, but it can be a little tedious to create what is essentially the same test multiple times. We copy a test, paste it and update the variables that matter. Maybe we do that several times. Then, if we need to update our tests, we update each copy of the test. The good news is, starting with version
23 of Jest, there is built-in support for creating data-driven tests.
Optimize Images in Your MDX Posts with the Next Image Component
Images are a great way to enhance your blog posts by clearly communicating ideas with visualizations and to add visual interest to your site. High quality images are great, but we need to take care to optimize our image size so we don't degrade performance. Lucky for us, Next ships with an
Image component that handles a lot of the optimization details for us.
Integrate the Next Link Component with Your MDX Content
Next provides the Link component to allow client side navigation. This is great when we're working directly in some JSX for a component or a page, but it's not quite as straightforward when we're trying to create local links in our markdown. We certainly could just expose the
Link component to the
MDXRemote component and use it directly, but I prefer to use markdown style links.In this installment of the Build a Blog with Next, MDX, and Tailwind Blog series, we'll create a
SmartLink component that uses a standard anchor tag with a
target attribute set to
_blank for external links and the
Link component for local links.
Add Page Titles and the lang Attribute in a Next.js App
Let's take care of some minor, but important, cleanup tasks. If we run an accessibility audit in lighthouse on our pages, we'll be notified that the
html element doesn't have a
lang attribute. The other minor item we'll be addressing in this installment in the series is the fact that our pages all share the same title.
Add a Skip Link Utility as a Tailwind Plugin
In an effort to start filling in some accessibility gaps, we're going to add a skip link to our site. This link will be the first element to receive focus and clicking it will jump the user past our header to the content area.We'll implement this as a TailwindCSS Plugin that we'll define right in our
Support Syntax Highlighting and Heading Links with MDX & Rehype
Our blog will be more beneficial for people if we can organize our posts with a hierarchy of semantic headings and provide links directly to those headings. For technical posts, we're also going to want to provide some nice syntax highlighting for code examples.We can solve for both of these needs (and many more) using Rehype plugins with the MDXRemote component.
Improve Blog Listing with Post Excerpts
If you've been following along, our sample blog site is coming along. Our blog index is currently just listing out our file slugs and displaying them as unstyled links. Let's give this page a bit more data to work with and clean up the styling a bit.
Include React Components in MDX Content
Markdown is great, but we're using MDX so we get the added benefit of being able to include React components in our content. In this installment of the Build a Blog with Next, MDX, and Tailwind series, we'll create a React component to include in our MDX content. We'll also use that same mechanism to replace a standard
HTML tag with our own version with our own styling applied with Tailwind.
Render Posts with MDX
Now that we've bootstrapped our Next app, configured TailwindCSS, and created some common layout with navigation and some styling, it's time time shift our focus to loading in the MDX content. In this article, we'll put together some sample content, install some dependencies, create the page for individual blog posts, and populate the page with MDX content based on the current URL slug. Let's do this thing!
Apply a Common Layout to a Next.js App
If you've been following along, you should have a site with very little in the way of content or design. Let's put some time into addressing the styling before we move on to addressing our lack of content in the next article in the series. Now that we have our app boostrapped and we've installed and configured Tailwindcss, let's create a common layout with some styling to apply to all our pages.
Configure Tailwind CSS for a Next.js App
In this article, we'll build on what we started in Bootstrap a Next.js Blog. We'll get the TailwindCSS integrated into our project, add a bit of styling to verify everything works, and cleanup unnecessary CSS that came with the default project setup.
Bootstrap a Next.js App with Tailwind CSS
In this post, we'll do some initial setup to prepare our project for the future posts in this series. We'll bootstrap a Next.js project, and we'll also install TailwindCSS and configure it to work with Next. We'll wrap up this post by adding some initial routes.
Build a Blog with Next, MDX, and Tailwind (series)
When I set out to rebuild this site, I had some specific capabilities in mind. First and foremost, I wanted a blog and digital garden that would be easy for me to maintain. I also wanted to capability to create and publish interactive content. Another key item for me was incredibly easy hosting and deployments. One last aspect that was pretty critical, was the ability to add more advanced functionality in the future if the need should arise. There are a lot of ways to accomplish all of these goals, but I chose to build using Next, MDX, and TailwindCSS. This combination allows me to write my content in markdown, add interactive elements with React, keep the amount of raw CSS I need to write and manage to a minimum, and with GitHub and Vercel, the hosting and updates are a breeze.
Creating a Problem Statement
As developers, we spend a lot of our time solving problems. Some of those problems are local and have a fairly narrow scope. A bug in a specific piece of your UI, for example. These small, focused problems are the type of thing we tackle regularly and can typically work through by reading the code, using debugging tools, logging values to the console, and asking for help from a teammate.Larger problems with a broader scope such as those related to system architecture, or organizational inefficiencies, however, can be a bit tougher to tackle.
Cycle Through an Array of Values with the Modulus Operator
Sometimes when we have an array of values, we need the ability to progress through the items one at a time. When we reach an upper or lower bound (one of the "ends") we can either prevent movement in the same direction, or we can circle back around to the value at the far end and allow progression to continue in an (potentially) endless loop.
State Machines As a Means of Collaboration
State machines and statecharts are an incredibly powerful way to manage the state of your application. In recent years, the XState library has made applying this approach to user interface development more popular. I'm a huge fan and have already promoted its use at two companies and seen it improve the developer experience and product quality in both cases.
Learn Function Composition By Building compose and composeAll Utility Functions
Think Before You npm install
Mocking HTTP Calls In Tests With Jest and MirageJS
Tests should be independent and isolated from external dependencies. That, of course, includes services that need to be called over a network connection. This means we end up needing to mock those calls over the network. In tests for front end code, this usually means mocking
fetch or a library like
Build a Bar Chart with D3 and React
D3, or Data Driven Documents, is the defacto standard for data visualization on the web. It's an incredibly powerful library that gives you all the tools you need to build just about visualization you can dream of.
Maintain Multiple VSCode Configurations
I split my time in VSCode between writing code and presenting programming lessons. Because of this, I need to maintain multiple configurations. One has all the settings and extensions I find useful for getting code written. The other is focused on sharing with others. It has higher contrast, larger fonts, and disables settings that could be distracting for an audience.
The Importance of Communicating Rationale for Decisions
For the past several years, I've been in positions where I spend a lot of my work time trying to align engineering, UX, and product teams. I have the combined responsibility of supporting business goals, considering the developer experience, and advocating for customers. In order to support these goals, I regularly make decisions that impact the tools and processes followed by various teams and hundreds of individuals and that ultimately, impact millions of customers.
Create A Card Flip Animation With CSS
Goals Heading Into 2022
The last couple years have been a roller coaster for all of us. Stuck in this seemingly endless pandemic, it's hard to keep track of time. In the last year or so, my family and I moved from the east coast to Michigan. I went through a pretty significant period of indifference toward tech, I changed jobs, and continued to feel pretty indifferent toward tech.
The New Next.js Based vanslaars.io
It’s a story as old as developer blogs. You sit down to write, something is broken or just not quite right, you get into some extreme yak shaving and the next thing you know, you’ve built a new blog and never did get around to writing that post!Welcome to my latest adventure in shaving Yaks! 😂
New & Improved React Course on egghead.io
I've uploaded a new collection on egghead. This is an updated take on my original React course, using new APIs and no more todo MVC!! 🎉 This time, we're building a minimal flashcard app. We start with create-react-app so we can get right into it.
Giving Thanks - 2019
I said it last year, and I'll say it every year. First and foremost, I'm thankful for my family. My wife is my partner in crime and has my back in the bad times and is there to celebrate with me in the good times. She is an outstanding mom to our delightful daughter. Our daughter is growing up so fast and she is honestly amazing. She's smart and thoughtful and has all the personality! Spending time with her brings me endless joy. They are my inspiration and the driving force behind just about everything I do.
Coming back to the Bullet Journal
A while back, I wrote about my use of a Bullet Journal. I reached a point, shortly after starting my current architecture role, where I felt like the use of an analog notebook wasn't the best approach for me. I was in all the meetings and taking in a ton of information (that hasn't really changed).
Code coverage should not be the goal
I personally write tests more for the purpose of driving my API design than for safety, but safety is a nice side-effect of good tests. Code coverage can be a good signal that you might need more tests, but coverage alone shouldn't be the goal. Focus on the right tests.
Don't DRY your tests
A lot of developers hear, Don't Repeat Yourself and apply the concept to code duplication rather than it's intended target, knowledge duplication. This often leads to overly complex code, aimed at removing a handful of characters that just happen to be the same shape if you squint hard enough.
Giving Thanks - 2018
Every year, I think I ought to write about all the things I'm thankful for, and then I don't. So this year, I'm just doing it. Adding the year as part of the title is foreshadowing to a future where I intend to do this annually, but may or may not actually follow through in any given year 😝.
Accessibility is important! With cypress-axe you can inject axe-core into your page under tests in a Cypress test and use it to check the DOM for accessibility violations.
Moving to Gatsby
In Defense of Teaching With Todo MVC
I've had two rather lengthy courses published on egghead.io, both based on building a todo application. As I write this, I am in the process of creating a tutorial for Cypress that consists of a series of videos and written material. This new material is also based on building a todo application.
The Value of Drawing Pictures
Words can be a hard way to convey a new idea. The more complicated something is, the more words you’ll need to explain it. Often, a simple drawing will get the point across where words have failed. Technical topics lend themselves to diagrams and flow charts. Even simple boxes and arrows, drawn crudely on a white board, can convey way more useful information than a beautifully crafted keynote slide that relies on words to get an idea across.
Functional JS: First Class Functions
Immutable Deep State Updates in React with Ramda.js
Basic state updates in React are a breeze using
setState, but updating deeply nested values in your state can get a little tricky. In this post, I'm going to show you how you can leverage lenses in Ramda to handle deep state updates in a clean and functional way.
Foster Your Projects
I have great admiration for people who foster dogs (or any animal really, but I’m a dog person so that’s where my brain goes). I love dogs, so much, in fact, my wife and I have 3 of them. The thought of bringing a dog into our household, caring for it, training it and then finding another home for it is hard. I think I would have a hard time doing that (and I don’t think a 4th dog in our house would be good for anybody), but I get it. People who foster dogs know that when they find the right home for a dog, they can save another one. They are doing what’s best for the animals they care for. It has to be hard, but it’s the right thing to do. The alternatives are to not help anymore animals, or end up becoming an animal hoarder and making the situation for the animals and themselves worse.
My First SitePoint Video
My first SitePoint.com video was published today! This video is the first in a series covering the key features in hapi.js.
My First egghead.io Video
A few days ago, my first egghead.io video was published! Build a Functional Pipeline with Ramda.js shows how to use Ramda's automatic function currying and data-last argument order to combine a series of pure functions into a left-to-right composition (pipeline) with Ramda's pipe function.
The Not Todo List
I have a long list of things I want to learn, stuff I want to build and content I want to create. I still want to do these things, but I need to be realistic about what I can actually accomplish without creating too much undue stress in my life.
MotorcycleJS - More Lessons Learned
One of the readers of my previous post was kind enough to point out that the way the final code sample in that post was written wasn't ideal. So I wanted to clear things up in a follow-up post.
Motorcycle.js And Lessons Learned The Hard Way
I have been playing with the CycleJS and it's sister project, MotorcycleJS for the past couple of weeks and I recently decided to use my goto approach for learning something new so I could gain a deeper level of understanding.
Learning By Preparing To Teach
I spent years as a technical trainer and as a result, I spent a lot of my time learning new things and also figuring out how to explain those things to people with less experience.
The Thing About Greener Grass
People like to say the grass isn't always greener on the other side. Those people are right, it isn't always greener. Sometimes, however, it is actually greener.
Undo a failed git rebase
Ever have a git rebase go wrong? Maybe you had merge conflicts and you missed something, but now that you've completed the rebase, it's hard to tell where things went wrong. Sometimes, in a situation like this, your best bet is to get back to a point before you started the rebase operation. Well, I have to tell you, it's actually pretty easy.
Why The Bullet Journal Works For Me
In my constant search for ways to be more productive and make my life easier, I discovered the Bullet Journal system, and now that I've spent some time with it, I'm loving it. I'm pretty sure I'm done looking for a digital solution for my day-to-day task management and event logging needs. Let me tell you why.