Chris Jarling

Website Redesing, Part 3: An MVP

It’s almost comical writing about this now, since so much time has passed since the last bit about me updating this site. But if you’re reading this now, you’re reading this on a new domain using a different tech stack and a new design. Both the tech stack and the design are different from what I outlined in the last post of this series. I want to talk about why it took so long and why it all changed so much.

The “why it took so long” part

There is two reasons for this: Life and me. Let’s talk about life first.

A lot of things happened in the past few month that demanded a lot of mental attention. First of all, I got married (hence the new domain, because the old one no longer fitted my last name). And while we did not have a big party, it still required a lot of administration work. Second, I started a new jobs at gigs in November (we’re hiring) and the interviewing process as well as getting settled into to role took some time. I did not have to work evenings, but with my family also requiring some time I was just to tired a lot of the evenings.

The second reason is me. Because to be honest, I had this redesign almost finished two times but then changed it all up again because it did not feel right to me. This, by the way, is why they say to never change your website design once you have it if you want to keep writing: It takes away all your time from the writing. The changes were in design and technological.

The design changes

I started this series out with a design I did in Figma and then went ahead to do the technical groundwork. By the time I finished that, I no longer liked the design. Objectively, it was fine, but it did not really feel like me. So I ditched it. I went for something new, a lot flashier. A lot of blurry, translucent backgrounds, a lot of colourful gradients. And again, objectively, that was a good design. But it did not feel like me. It felt like I forced it to be there. So I threw it out again and started with the bare minimum: A font combination I liked and a color I liked. I only added to that what I needed and that’s what you are currently seeing. A very minimalistic approach that might not scream “I do frontend development in react” in you face, but one I like.

What also changed is the design process. It‘s now designed in code. I always wanted to design in code in the past, but never felt productive with it. I think with React, Next.ja and Tailwind, I now have a system in place that allows me to iterate quickly and with a decent experience for myself.

Wait, Next.js? Haven’t I written about how I wanted to use Gatsby for the redesign in the past?

The technical changes

I built blogs and personal pages in Gatsby before, and I like it. Hence the initial choice. But I worked a lot with Next.js lately (especially since I had to learn it for my new job) and it feels like a better fit for what I want to achieve here.

Now, don’t get me wrong. I think Gatsby is a great tool for building static sites, but I felt it was a bit limiting in that. This site has grown a lot in the past, from just a blog to other pages. I want to keep that going. And I don’t want to be limited by the underlying technology in terms of what I can build here. I may never need that flexibility, but I want to have that option. Also, I don’t like writing GraphQL queries for everything.

It’s more of an addition instead of a change, but I also use Tailwind now for styling. It allows me to move fast and try out different things in the design. I feel like Tailwind is a controversial topic right now, but I like it. Yes, the class strings of elements get long. I can live with that.

The current state

The site currently is a little rough about the edges. It does not have all the features I initially wanted to add. It is even missing some of the pages from the old site. But I wanted to finally get it out of the door. You know, we’re all agile and lean over here. I still have a lot of stuff I want to do, but I also want to continue writing and not feel the shame of publishing under my false name. Posts and notes are here as well as all pages that (hopefully) will make sure I don’t get sued. Everything else will come with time.

Read more →

Goals

As one does, I recently planned what I wanted to do this year. I realized how much my approach to this changed over the years, especially regarding goals I want to achieve. I wanted to write about that a little. Why, you ask? Because I set out to write a certain amount of blog posts this year. And hence, we now have to work through this post about goals so I can achieve my goal. Hooray.

Okay, goals. If you look around the internet, you will read over and over again that goals are important. I think this is true: If you don‘t know in which direction to run, you may end up somewhere but chances are your just running in circles. But I also don‘t think that you have to have a 10 year plan you follow in order to come by things you enjoy. I think goals are allowed to and definitely should change.

You constantly learn new things. You learn about directions you can possibly go in your journey that you did not even know existed when you started. It would be foolish to not at least evaluate the new directions and change course if they interest you.

For example, when I finished school there were a few broader directions I was interested in: Writing, photography and designing things on the web. I played around in all directions a little and decided that I will mainly focus on the web thing. I studied in the informatics field (because I was to lazy for the art school assignments you have to do to get accepted) and had in mind that I wanted to be a designer in an agency. So during and after my time in university, I did just that. I enjoyed it until I didn‘t. I then noticed that I also like programming and it turns out a decent programmer with an eye for design is really valuable in small teams. So I did this for a while. Then I realized that there are people working on products and they don‘t have to start a new project every 3 months and I decided I wanted to do that. This is where I am now.

All of this happened over a span of roughly ten years . I could not have planned to be where I am today 10 years ago, because I did not know that place existed. Likewise, I cannot plan where I will be in 5 years or 10 because many of the places I could end up I either don‘t know about or they don‘t exist yet. I think making concrete plans for the long term is really limiting. I have a rough feeling of which directions feel good to go and which not. I will try to go where it feels good. And if something interesting comes by on the way, I will take a turn and see how that feels.

Read more →

Things I learned in 2022

I recently did my annual review and wrote down some things I learned this year.

Here they are, in no particular order.

  • Taking risks and leaving your comfort zone is always worth it. You will make new experiences and no matter how they turn out will you always learn something valuable as long as you keep your eyes and mind open
  • Tools don’t matter that much. Settle for something that works and only start min-maxing if it gets in your way. The note taking tool or the keyboard you use make only a marginal difference. Focus on the hard things instead.
  • Don’t be afraid to look stupid. Usually, if you have a stupid question, at least one other person in the room has the same question and is afraid to ask. Also, this is how you learn.
  • Do not care about what other people think of you. Because when you do, you live your life to their expectations and this is the road to unhappiness. Get comfortable with being judged.
  • If you have the chance to help someone, do it. You will feel a lot better afterwards and you almost always learn something on the way.
  • No matter the kind of relationship, if it drains you you are allowed to cut it. Successful people say goodbye.
  • Contact people from your past you felt a spark in at the time meeting them. Most of the time, there now is a fire where that spark used to be.
  • Write. Whatever it is, once you have written it down, it will become a lot clearer. It forces you to order your thoughts and take a differentiated point of view.
  • Speak slower. People will understand you a lot better. The optimal pace is right at the edge where you feel people must think you are stupid. They really won’t notice a difference other than your improved pronunciation and fewer “ehm”s
  • Don’t read the news. The only impact it will have on your life is the negative influence on you mental health.
  • If you are going places, some people might not be ready for it and leave. That’s okay. Some people are only meant to be there for a season.
  • If you wander off the beaten path of society, people will start talking about you. If you are sure this is the right way to go, the amount of shit people talk about you behind your back is a good indicator on how you are doing.
  • If you know your escape mechanisms, they can serve as a tool to indicate if there is something in you life you need to deal with.

All these Promises

Here’s the different methods of handling an Array of Promises in JavaScript.

Promise.all()

Probably the best known of them all. We tell JavaScript “We need all these Promises to fulfill”. Thus, Promise.all() will stop executing any further promises on the first promise it encounters that is rejected.

const promise1 = Promise.resolve(13)
const promise2 = Promise.reject(37)
const promise3 = Promise.resolve('foo')

const results = await Promise.all([promise1, promise2, promise3])
console.log(results)
// => [{status: 'fulfilled', value: 13}, {status: 'rejected', reason: 37}]

Promise.allSettled()

Similar to Promise.all(), but will not stop executing on the first rejection and follow trough until all Promises are settled.

const promise1 = Promise.resolve(13)
const promise2 = Promise.reject(37)
const promise3 = Promise.resolve('foo')

const results = await Promise.allSettled([promise1, promise2, promise3])
console.log(results)
// => [
// {status: 'fulfilled', value: 13},
// {status: 'rejected', reason: 37}
// {status: 'fulfilled', value: 'foo'}
//]

Promise.any()

With Promise.any(), we’re telling JavaScript that we need any of the passed Promises to resolve. We do not really care which one, as long as it is at least one. JS will then return the first one to resolve or an AggregateError if none resolved (we usually want to handle that).

const promise1 = Promise.resolve(13)
const promise2 = Promise.reject(37)
const promise3 = Promise.resolve('foo')

try {
  const result = await Promise.any([promise1, promise2, promise3])
  // Do something with our result
} catch (error) {
  // Do something to handle the error case in a meaningful way
}

Promise.race()

Again, this is very similar to Promise.any(). The main difference is that Promise.race() will take the first settled Promise (which can be resolved or rejected), whereas Promise.any() will take the first resolved Promise.

const promise1 = new Promise((resolve, reject) => {
  setTimeout(resolve, 500, 'one')
})

const promise2 = new Promise((resolve, reject) => {
  setTimeout(reject, 100, 'two')
})

try {
  const result = await Promise.race([promise1, promise2])
  console.log(result.value)
} catch (reason) {
  console.log(reason)
}

// => "two", because promise2 rejected faster than promise1 resolved
Read more →

I had a commute today

I decided to go to the office today, which meant I had a commute. I hated every minute of it. It takes me about 50 minutes from door to door with public transport. I’ll consider this a lengthy commute.

Here’s a list of annoyances from my rides:

  • Dude Smoking heroin at the station at 9 a.m.
  • People not caring at all about masks being required on public transport
  • Random dude screaming at a woman because she was standing in the door area (there was no other place where she could have gone)
  • Woman refusing to pick up a toy for her toddler because „You dropped it“, toddler screaming in protest (and rightfully so).

All in all, this took a lot of energy and time and was a great reminder of why I love working from home.

It’s also a great reminder why companies should let their employees choose from where to work. My energy might get drained from encounters with a lot of people. Yours might not. You may even like it.
Neither of us should be forced into a situation that’s subpar for us.

Read more →

Using ResizeObserver

You probably know about the resize event on the window object you can listen to. But there are situations where it is needed to know about size changes on single elements.
This is where ResizeObserver comes in. With ResizeObserver you can define a callback that should be fired upon resize of an Element or SVGElement. Let’s take a look.

We will explore the API by solving a fictitious problem:
We need to know when a div with the id my-div resizes and broadcast the new height of the element to a function, functionThatUsesTheNewHeight().

To accomplish that, we’ll need to:

  1. Instantiate a new ResizeObserver, define a callback and pass it to the observer
  2. Observe an element

Instantiating a new ResizeObserver

Creating a new ResizeObserver uses the syntax

new ResizeObserver(callback)

However, we want to store the instance in a variable, to us it later on:

const observer = new ResizeObserver(callback)

This is straight forward, but what will be out callback?

Defining the callback

The callback function takes two arguments, entries (the observed elements) and observer (the ResizeObserver itself).

A callback function could look like the following:

function callback(entries, observer) {
  for (const entry of entries) {
    // Do something with each entry
  }
}

Note that entries is an array, as one observer can observer multiple elements.

There are a few things we need to change to make the callback work for out scenario.
First, callback is a bad name for the function. It worked for the code examples above, but from now on, we’ll name our callback function handleResize.
Second, we don’t need the observer and will omit it.
And third, we are observing a single item and will not loop through all entries (as we are sure there will only ever be one).

Our callback would look like this:

function handleResize(entries) {
  const height = entries[0].contentRect.height
  functionThatUsesTheNewHeight(height)
}

entries is an array of ResizeObserverEntrys. They have a lot of interesting attributes, but for our example, the contentRect is the most interesting, as it contains the height of the element.

Observe the element

The last step is to connect out observer to the target element. To achieve that, we have to get our div and pass it in our observer:

const myDiv = window.getElementById('my-div')

const observer = new ResizeObserver(handleResize)

observer.observe(myDiv)

And that’s it. We now know about size changes in our div and broadcast the new height to out target function.

Teardown

As with event listeners, it’s a good idea to clean up after us once we no longer need the observer. ResizeObserver offers to methods for this: unobserve() and disconnect().

unobserve() takes a target as an argument and stops the observation of the specified target. Had we defined more than on target for our observer to observe, the others would have been left untouched.

disconnect() in contrast, will unobserve all observed targets of the observer.

Read more →

False assumptions

Louis Antonopoulos (thoughtbot):

I immediately realized the trap I had fallen in. I made an assumption (no key in backpack) and I held onto that assumption for days like it was the truest thing in the world. And that simple action, repeated over and over, led me down a trail of wasting time, feeling frustration and worry, and taking all these extra steps.

This is something I fall for as well, and fairly often. I make it a conscious effort to remember to ask myself if what I think is happening is actually happening. But it’s hard to break your thought process and think about it when you are happy about being oh so smart that you know what’s happening right away. It will take time.

To Louis’ list, I’d like to add

  • I fixed the bug in one place, so it is gone for good
  • If something important was broken and it somehow passed the tests, exception tracking will catch it for sure
Read more →

I bought the wrong smartwatch

I bought a Fitbit Charge 5 a few months ago. I think it was a mistake.

On paper, it ticks a lot of boxes that are important for me. I want a device that I don’t have to worry about while wearing it. A device that I can wear while exercising and in the shower and at all other places. I want it to track certain things. Most important to me are my heart rate, my steps and my sleep. And I don’t want to worry about how much battery is left all the time.

The battery thing was the main point I chose trackers/smartwatches by in the last few years. That’s why I owned a Fossil HR Collider before the Charge 5. Because it had an e-ink display I had to charge it about once a month.
Battery life is great on the Charge 5 as well. I can go a week or two without charging. Also, sleep tracking is accurate, and they have an API to get your data. That’s all the points I have on my list of positives.

Let’s talk about what I do not like about it.

Syncing to the App

To make use of the data, I have to look at it in the Fitbit App. I can see the data of the current day on the bands display, but that is not useful except for the current step count. For any insights (e.g. on sleep) or long term trends, I have to use the app. To get any data from the band to the App, I have to open the App and initiate a data sync by hand. That’s tedious.

The App

The app itself works fine, but using it feels clunky at times. The interface looks dated. Also, it feels like constant upselling for Fitbit Premium. The band comes with 6 months of Fitbit Premium for free, in theory. You have to buy a year of premium to get your 6 months, though.

No Widgets on iOS

I mean, come on. There is a feature suggestion that is open since 2018. I get that not every app offers widgets, but in this case it would make sense. Increases the feeling that Software is not that important to Fitbit I contrast to hardware sales.

Updating the Firmware

Updates require (or at least it is recommended) the band to be connected to power and the phone has to be nearby. I get that, that’s how other devices do updates. The App told me it might take up to 45 minutes and That feels long. You can argue that it does not happen frequently and you can continue using your phone during the time. But it feels long.

Watch faces

There is a handful of watch faces you can choose from. They all don’t look great.

This all reads bad. It’s not that bad. The device does what I bought it for at a cheap price. Still, these things bother me. To be honest, this whole post was probably just written to justify buying an Apple Watch sometime in the future.

Read more →

On children and behavior

I thought about the behavior of children today. Especially the kinds of behaviors in children we might not like. I think it might be all our fault.

I want to say a few things before I go on, because I’m afraid that this might sound wrong if I don’t. It is my strong opinion that it is not a child’s job to be how a parent wants them to be. They do not owe parents a thing for bringing them into this world. I think parents owe their children for bringing them into this world and one of these things it to allow them to be how and who they want to be.

Yet again, there might be certain behaviors that parents don’t like in their children. I can love someone dearly and not like some things they do. It took me a while to realize that.

Back to my point.

Children imitate the people around them. This was a gut feeling I had until a few hours ago that was based on my experience with one child. After reading up on it, I can confirm it is more than a gut feeling.

Over and Carpenter:

One of the most important messages that imitation may convey, however, is “I am like you” or, at a group level, “I am one of you”

Chances are that you as a parent are a person your child spends a lot of time with. This leads me to the idea that, maybe, it might be a good idea to look inwards first if you notice behavior you do not like.

Child screams a lot? How’s the tone in the house?
Child does not want to eat when food is on the table but is hungry half an hour later? How do you eat? Do you take time? Do you yourself eat regularly?

I know that this is
a) hard
b) a naive theory

But maybe give it a try. Here are Over and Carpenter again:

[…] 5-year-olds work to ensure that a model can see their imitation, thus suggesting that their imitation was produced for the model

Read more →

Website Redesign Part 2: (a little) Design

In the last post of this series, I wrote that I tend to get bored with creating designs at some point in the process and want to start coding. I now have reached that point.
My joy of creating designs lasted shorter than I thought and currently, I have designs for three pages: The homepage, the blog overview and a single blog post. While this is a lot less than I aimed for, it will give me enough of a base to start coding and even design other parts of the page in code. I might come back to Figma later in the process if I get stuck.

Before going into the details of what I did with the pages, here’s the link to the Figma project, if you want to look around: Link
It’s not super clean, I don’t use components everywhere I want to, but its what I could do in the time and with the motivation I had.
Now, let’s jump into the details.

The homepage

Final homepage design

Not a lot has changed here. I cleaned up the spacings to get a feel for which dimensions I want to go for. Currently, I’m using multiples of rem, which means all spacings are multiples of 16px. I’ve done this in a lot of other projects and it worked fine.

The one thing I did change were the underline-background-hybrids I used for the “Continue Reading” and “Project Details” links. They felt too playful and somewhat forced, almost as if the page screamed “look how cool I am”. And if there is one thing that does not make you cool, it’s saying how cool you are. Here’s a direct comparison:

Comparison of "read more" link styles

Color-wise, I like the neon green in the header, as it draws a lot of attention to the email I want people to contact me at. Using the green in that many other places on the site made it loose its value. I went with the orange instead and used a pale version of the green on the divider instead.

Looking at the page now, I feel it looks like a more confident design. I might even go back and remove the color on the links altogether. Not sure about this, though.

The blog post overview

Finished post overview desgin

Not much to talk about on this site. I feel like the only big question on these sites i wether you want to display

  • Only the titles
  • The titles and an excerpt
  • The full posts

I went for only the titles (and the tags, more on them later) here. Partly because that’s the way it is currently implemented and I like it, partly because I like an overview to be clear and give an… overview on which articles one can find here.

I originally added the tags because the site looked bleak and I wanted it to be more colourful without adding arbitrary elements. In addition, the tags give visitors a quick overview of the topics of the blog, even though they might not understand the titles of all posts.

There is no pagination in the design, even though I will need one. A pagination seems to be the one of the things that you design and then you end up using it and it feels weird. I will prototype that in code and then make it look good.

Single post

Finished single post desgin

The content did not change a lot compared to what I currently have. The date was moved to the top, that way all the meta data of the post is at the top. The images now are wider than the content. I’ve always liked that and this is why that’s here. Sometimes, that’s enough justification.

The “written by” may feel weird at first, because I’m the only author of this blog, but I added it in preparation for micropub and having a author card on my content. There is more that I’ll need to add on this page regarding webmentions, but I have not read into that topic enough to make design decisions on this yet. This will have to happen later, either in code or in Figma if it turns out to be complex.

The bottom section (I don’t want to call it CTA) is more present because I want RSS to be cool again and also I want to be bought coffee.

Other post types

I though about other post types in this context. What I currently think of are link posts (like on daring fireball) which I had in earlier blogs of mine and want to have again. Photo posts might be a possibility as well (even though they would live in notes, I guess). I decided to have those post types as distinct feeds and not mix them with longer posts.

Now what?

Now I will go ahead and do a git init, set up Gatsby and a naive blog and then read into micropub and webmentions and try to get those to work as a first step. Well, now I will go to bed. But sometime in the future, git init and things.

Read more →