aboutusesTILblog

Today I Learned

Get the RSS feed for Today I Learned

TIL, it’s pretty easy to stack elements in CSS, without having to use positioning! It’s a litle bit more verbose to do it in tailwind, but it’s the same idea.


.parent {
  display: grid;
}

.child {
  grid-area 1 / 1
}

Top Card

This card is on top... hover me!

TIL about feed, an npm package that allows you to quickly generate an RSS feed for your website!

I used it to generate an RSS feed for my blog and my TIL feeds! It’s pretty simple and super easy to plug into your existing project.

Check it out

TIL about coolors.co — a superfast color palette generator. If you’re anything like me, you’ll probably use it whenever you need to generate a color palette for your side projects, you know, those side projects that you’re totally working on and not abandoning for a while.

Check it out

I learned this hard lesson today. Optional chaining is for uncertain values — not uncertain existence.

If I’m not sure if a global object exists, I can’t rely on optional chaining to access it. I have to check for existence first.

// 👇 this is a valid expression in node
// we check to see if window exists
if (typeof window !== 'undefined') {
	window.localStorage.setItem('key', 'value')
}

// 👇 this is not a valid expression in node
// window is undefined (its existence is uncertain)
window?.localStorage.setItem('key', 'value')

TIL about the node-modules-inspector — a package that allows you to visualize your node_modules folder, inspect your dependencies, and so much more 🤯! I’m a big fan of the visualizations, since I’m more of a visual kinda person. You can use it in your own project with this simple command: npx node-modules-inspector.

Check it out

TypeScript’s compiler is being reimagined. Currently at version 5.8, TypeScript is still written in TypeScript itself, but there are plans to port it to Go for version 7.

This change promises to improve compilation times—by up to 10 times faster! True, the speed boost is something we probably won’t see for a few months or years, but I’m super excited to see Go get some much needed love and attention, since you know, it’s my secondary language of choice.

TIL about Magnesium Glycinate, a supplement that helps promote better sleep! I’ve been having a tough time falling asleep lately, especially after a tough Brazilian Jiu Jitsu practice, or an intense workout. One of my friends recommended Magnesium Glycinate as a way to help me sleep better. Let’s see how it works… I just ordered some today 😆!

css05.03.2025

Fontsource

TIL about Fontsource, a free Vercel resource that provides you with information on how to easily install and self-host web fonts. They support all Google Fonts, as well as open source ones!

Check it out

js04.03.2025

Tanstack Form

TIL: Tanner Linsley, the creator of TanStack Query, Router, and Start, just dropped TanStack Form!

True to form, it’s framework-agnostic, headless, and has zero dependencies. It also handles deeply nested objects out of the box, making it a powerful alternative to traditional form libraries.

Check it out

TIL about a growing movement on the web where people are choosing to use system fonts instead of loading custom fonts. Over the years, the default system fonts included with operating systems have become quite robust and visually appealing. If you’re concerned about performance or don’t require a fancy web font, this could be a great solution for you.

Check it out

This one’s pretty sweet and I’ve been reaching for it a lot lately at work! Rather than having multiple className conditions, you can use a data-attribute to manage your state.

This is not only a great way to keep your component clean but also allows you to target any state pertinent to your component without JavaScript! Mind you, I’m assuming you’re using something like Tailwind for your styling.

// no reliance on utility functions like `twMerge`
<div
	data-state-can-scroll={canScroll}
	className="data-[state-can-scroll=false]:hidden"
>
	Hidden when canScroll is false!
</div>

TIL about wxt! It’s like Nuxt but for web extensions.

Check it out

cool tech14.02.2025

sqoosh

TIL about a local first tool for image compression called sqoosh. No more sending images to random servers just to compress them! 😆.

Check it out

TIL about bolt.new, an AI-powered web agent that lets you deploy apps via Stackblitz. It’s a pretty sick way to throw up a demo of a new app to illustrate a concept.

Check it out

css08.02.2025

CSS tidbits

TIL about the following…

inset-property.css
    /* top, left, right, button, are all set to to the same value */
    .box {
      inset: 0;
    }
  1. The inset property is a shorthand for top, right, bottom, and left properties.
  2. Absolute elements can only be contained by other elements using Positioned layout.
  3. Positioned elements will always render on top of non-positioned ones
  4. Stacking context is the stacking order of elements that are positioned.
    • We can create a stacking context by combining a non-static position with a z-index. So position absolute and z-index will create a stacking context.
    • We can also create one by setting opacity to less than 1.
    • Check out the link above for more info.
  5. The isolation property allows you to create a stacking context. We can add this to a parent element and then we can forget about having to add a position: relative and z-index to the children. It is the lightest weight way to create a stacking context.
  6. The z-index property can be used in a flexbox the same way as it can be used with a positioned element.

TIL about the stacking context inspector. It’s a tool that allows you to inspect the stacking context of an element.

Check it out

More of a public service announcement and a reminder to myself (especially for my personal projects), to leave comments on any funky things you’re doing in code. I wasted an hour battling a bug in my blog because I didn’t leave a comment regarding a @ts-ignore directive.

Leave. Comments. Please.

js30.01.2025

reach.tech

Kent showed me a great way to have a stable id for my react components, between server and client renders.

Ideally, you would be reaching for useId from react but if you’re using an older version of react, like 17 or 16, then you can use auto-id from reach.tech instead.

Check it out

cool tech29.01.2025

zoxide

Til about zoxide which is a faster and more robust cd alternative; it lets you navigate your filesystem faster and more reliably.

zoxide-examples
 z ~/Documents/new-blog
 z ~/Documents/rehype-code-titles

# Go back to the last directory (new-blog)
z -

# Go to the `new-blog` directory
z rehype-code-titles

# Go back to your home directory
z

# open a fzf menu of possible entries that begin with `re`
zi re<SPACE><TAB>

Check it out

TIL about the Standard Schema! It’s an effort to standardize the interface of TypeScript validation libraries.

To pull directly from the docs, The goal is to make it easier for ecosystem tools to accept user-defined type validators, without needing to write custom logic or adapters for each supported library.

TIL that you can edit the whole document with document.designMode = 'on'!

Toggle document.designMode

Check it out

Happiness = results - expecations-unknown

Today I learned about the with method on the Array.prototype object. This method is used to create a shallow copy of an array but with one element replaced at a given index.

const arr = [1, 2, 3]
const newArr = arr.with(0, 5)

console.log(arr) // [1, 2, 3]
console.log(newArr) // [5, 2, 3]

This is useful when you want to replace elements in an array without mutating the original array.

Check it out

js07.12.2024

docsify

So it’s even easier now to add a documentation website to your project! While looking over the Zod github repo, I saw that they were using docsify to house their documentation. It’s pretty slick and I intend to use it for my own projects… well at least the work ones 😆.

Check it out

If you’re not using a meta framework like Next.js or Remix, I’d high suggest you check out react-error-boundary.

Seriously, Taran, use this at work.

TIL about how one can use satisfies in typescript, without satisfy at all!

// taken right from Kent's blog
type OperationFn = (left: number, right: number) => number

// this is a restriction on the operations object
// but with satisfies, I leave myself room to add more operations and don't need to manage another type
const operations = {
	'+': (left, right) => left + right,
	'-': (left, right) => left - right,
	'*': (left, right) => left * right,
	'/': (left, right) => left / right,
} satisfies Record<string, OperationFn>

Check it out

TIL there’s a tool that can help you find out if your types are wrong for your library!

Check it out

Til about raycast! The productivity tool that our macs should have shipped with ❤️

Check it out

Struggling to choose the right license for your project? There’s a great tool for that!

Check it out

finance22.10.2024

wave app

TIL about wave app! I’m using it to track my expenses and the invoices for my company! It’s pretty cool.

Check it out

Sick of seeing truncated Objects in Node? I got you bro (well Matt Pocock has got you).

let deepNesting = {
	level1: {
		level2: {
			level3: {
				level4: {
					level5: {
						name: 'Moderately Nested Object',
						value: 42,
						attributes: {
							created: '2023-10-01',
							modified: '2023-10-15',
							tags: ['demo', 'test', 'nested'],
							metadata: {
								author: 'Jane Doe',
								version: '1.0',
								license: 'MIT',
							},
						},
						items: [
							{
								id: 1,
								description: 'First item',
								status: 'active',
							},
							{
								id: 2,
								description: 'Second item',
								status: 'inactive',
							},
						],
					},
				},
			},
		},
	},
}

// logs: { level1: { level2: { level3: [Object] } } }
console.log(deepNesting)

// You get the whole object!
console.dir(deepNesting, { depth: Infinity })

Matt is the man!

TIL there’s a useful github repo for bulletproof react!

It gives you a bunch of useufl tips and explanantions on how to make your react code bulletproof.

Check it out

TIL that you can use console.log with color!

console.log(
	'This is %cMy stylish message',
	'color: yellow; font-style: italic; background-color: blue;padding: 2px',
)

Check it out

Need a tool to help you manage your versioning and changelogs? Check out changesets!

Today I learned how to create multiple Neovim Configs. I’ve set up a home and work config respectively.

TIL about git recent by Paul Irish. It’s a command that shows you your latest local git branches! Super useful when you’re at work and got a lot of stuff on the go.

 git recent

# example output
:'
* main                         7167899 (19 hours ago) Taranveer Bains
                               new til

  feature/partytown            548eaf3 (2 days ago) Taranveer Bains
                               chore(dev-server): update dev script
'

Check it out

Interpolation is defined as “the insertion of something of a different nature into something else.”

backend09.09.2024

orbstack

TIL about orbstack — a fast and lightweight way to run containers on a Mac!

TIL that there’s a tool to help you apply color filters to your dom nodes!

Check it out

TIL that Storybook has a way to specify the behavior of argsArgeTypes. This is a great way to constrain the values that your component can accept and provides information about args that aren’t explicitly set in the story.

// Replace your-renderer with the renderer you are using (e.g., react, vue3, angular, etc.)
import type { Preview } from '@storybook/your-renderer'

const preview: Preview = {
	argTypes: {
		// 👇 All stories expect a label arg
		label: {
			control: 'text',
			description: 'Overwritten description',
		},
	},
}

export default preview

Check it out

Keep away from people who try to belittle your ambitions. Small people always do that, but the really great make you feel that you, too, can become great.

-Mark Twain

TIL about e18e (Ecosystem Performance). It’s an initiative to connect folks and projects working on improving JS package performance.

Check it out

TIL that if we want to make a deepClone of an object in JS, there’s a built in method in most browsers: structuredClone!

The old one (which works but doesn’t account for things like Set and Map or even Date)

the-old-and-new-way
const originalObject = {
  name: "John",
  age: 30,
  date: new Date(),
  details: {
    hobbies: ["reading", "gaming"],
    address: {
      city: "New York",
      zip: "10001",
    },
  },
};

const clonedObjectOldWay = JSON.parse(JSON.stringify(originalObject));

// what do you think happened to the date? 😏
// hint... no longer a string!
console.log(clonedObjectOldWay);

console.log(originalObject.date instanceof Date); // true
console.log(clonedObjectOldWay.date instanceof Date); // false (Date is not preserved)

Shout out to Matt Pocock — the person behind Total Typescript — for the twitter thread that exposed me to this function!

Check it out

Don’t forget this brother. My guy hit me hard with this; it was too damn early in the morning for them ninjas to be chopping onions 🥲!

Do what matters with who matters, while it matters.

-Mark Techson

TIL that the button html element accepts a form attribute. This is cool because it allows you to associate a button with any form, even if it’s not a direct ancestor of our button! How cool is that ❤️!

Check it out

TIL margin is meant to increase the distance between siblings. It is not meant to increase the gap between a child and its parent’s bounding box; that’s what padding is for.

width looks up the tree but height looks down the tree. An element’s width is calculated based on its parent’s size, but an element’s height is calculated based on its children.

Thanks Josh Comeau!

😆 while going through a CSS workshop, I came across this list of CSS mistakes. Be humble folks. We all mistakes.

Here’s a list (probably not complete) set of inheritable css properties.

TIL, from Dom Farolino that he’s trying to make addEventListener extinct with the observables api!

// Filtering and mapping:
element
	.on('click')
	.filter((e) => e.target.matches('.foo'))
	.map((e) => ({ x: e.clientX, y: e.clientY }))
	.subscribe({ next: handleClickAtPoint })

Check out this dope tool for understanding the React internals! So dope!

Never make a decision in anger, and never make a promise in happiness

-Imam Ali Ibn Abi Talib

TIL about an app that’ll edit your prose for you! Hemingway App should be able to help me write with better clarity and conciseness. I’m a wordy son of a gun.

js08.05.2024

patch-package

Got a node_module giving you a headache? Need to give it a band-aid? Thank your lucky stars for patch-package.

It’s a vital band-aid for the bleeding edge!

You must be willing to suffer the anger of your opponent, and yet not return anger. You must not become bitter. No matter how emotional your opponents are, you must be calm.

Anger is incompatible with joy.

Our goal is not to remain calm while suffering but rather to experience a setback without thereby suffering.

css01.05.2024

unset

TIL about the unset keyword in CSS; it resets the property value from the one it inherited from its parent and it it doesn’t natrually inherit from its parent, it sets it to its initial value.

Check it out

js30.04.2024

bundlephobia

If you ever want to know (sort of) the cost of adding a package to your node app, you can use bundlephobia!

TIL that Kanak Di Rakhi is a Punjabi song that me and the Boys wild out to. It’s a banger. It came out in 1959 and is a must listen to and dance to at any reception.

how-to-find-and-replace-in-vim
"while in your quick list
:cdo s/your-search-term/thing-to-replace-with/g

"go to quick list after changes
:wa <CR>


During office hours with Kent, I learned about semver calculator!

It seems pretty dope and I’m going to use it in the future!

js10.04.2024

GROQ

I also learned that Sanity has their own query language for working with JSON. Might be worth looking into if you need to do some transformations and just move it into the query versus doing it in the code.

Check it out

TIL about a sick template for building a headless shopify theme with Sanity and Hydrogen.

Check it out

If you pass in a name, it’ll behave like an actual accordion. Thanks Adam Argyle!

Check it out

js14.03.2024

trigger.dev

Need to run background jobs? Not writing Ruby On Rails and therefore not using Sidekiq? Check out trigger.dev

I can probably use this somewhere in the future but TBD 🤔!

TIL about dotenv.org! You can use this to share and sync your .env files across machines/teammates. They also allow for the ability to encrypt your secrets and use them in your CI/CD pipelines.

The neat thing about this if someone leaves your company and you don’t have a fancy IT setup, you can just change the keys on the dotenv side of things and the keys the user has on their local machine will no longer be valid!

We tried to use some CSS variables we defined inside of the :root with our tailwind config and even though tailwind let’s you do that, the outputted CSS isn’t actually valid 🤯! The media query declarations are processed while our CSS is being parsed!

wont-work.css
:root {
	--mobile-breakpoint: 600px;
	--tablet-breakpoint: 900px;
}

/* This gets processed before the CSS is parsed */
/* So the media query is invalid */
@media(max-width: var(--mobile-breakpoint)) {
	.showMeGoing {
    visibility: visible;
  }
}
css19.01.2024

stylex

So there’s a kind of new styling solution for the web called stylex brought to you by Facebook. I haven’t used it yet, but damn, it looks neat y’all.

Check it out

TIL that you can inject other non SVG XML into an SVG document. From our context, that means we can inject some HTML elements in the SVG. I’ve used it once at work and it was kind of nice 😃.

Check it out

To gamble on yourself is to risk failure. To do it in public is to risk humiliation.

Our fear, like a self-indicating arrow, points to the things we ought to do.

Want to have some type hinting for a union but allow any string value?!

Use this hack bruh:

type color = 'red' | 'blue' | 'green' | (string & {})

function getColor(c: color) {
	console.log(c)
}

getColor('red') // editor will code complete this for you
getColor('yolo') // this works!

Alright, I’m not the greatest at CSS, but I respect those people, such as Josh Comeau that are! TIL (from reading his blog post) the following about some CSS attributes and how they relate to grid:

  • justify: deals with columns
  • align: deals with rows
  • content: deals with the grid struture
  • items: deals with the DOM nodes within the grid structure

For example, align-items: center can loosely be translated into: In the context of the row, these DOM nodes, center them... bro. Seriously, go read his article.

Check it out

It’s easy to judge. It’s hard to know. Until we know the reasons why a man acted the way he acted, we cannot say that he acted wrongly.

Waste not a moment questioning a man’s courage. Put the scrutiny solely on your own.

It’s okay to be scared, but, be not afraid. Being scared is a reaction to an event; it’s an ephemeral feeling. Be scared when something pops out of a haunted house, but, be not afraid of ghosts. Be scared when you are about to go give a presentation but be not afraid of speaking your mind.

It’s okay — being scared alerts you, wakes you up, and brings danger to your awareness. Being afraid though? This is a state of being. It weakens you, drags you down, and sometimes, paralyzes you.

Be not afraid.

Turns out you can not only transform JS into an AST, but even SQL statements! Pretty nifty.

Check it out

See things for what they are. Do what you can. Endure and bear what you must.

If you’re ever having issues with neovim, it might help to clear out the cache. I recently was running into issues after switching from packer for my dependency management to lazy and there was a sneaky little devil 😈 in the cache directory causing issues.

You can view the cache directory here: $HOME/.cache/nvim/.

While working on my todo app, written in go, htmx, and lit, I forced myself to get a better idea of how OAuth worked! I’ve used it before, but I never really understood the flow.

This youtube video really does a good job summarizing exactly what’s going on ❤️ !

Not gonna lie, I’ll probably never need to reach for this tool 😂, but I heard about it while watching a video on Youtube and thought it was cool. react-reverse-portal allows you to render a react node and then take it out of the dom entirely and return it later, without having to unmount the component. It’s pretty neat!

Check it out

js11.10.2023

vercel serve

TIL about serve by vercel. It lets you serve your SPA/static files, incredibly easily! We may or may not be using it at work for some of our SPAs 😉.

Check it out!

TIL that golang allows for empty switch statements in the condition block. This is not possible in JavaScript! The reasoning behind this is that the switch statement in golang is not limited to only comparing values. Below you can see two versions of branching logic — one with the switch and one with else ifs 😊.

with-switch.go
package main
import "fmt"
func main() {
    i := 10
    switch {
    case i < 0:
        fmt.Println("Negative number")
    case i == 0:
        fmt.Println("Zero")
    case i > 0:
        fmt.Println("Positive number")
    }
}
no-switch.go
package main
import "fmt"
func main() {
    i := 10
    if i < 0 {
        fmt.Println("Negative number")
    } else if i == 0 {
        fmt.Println("Zero")
    } else if i > 0 {
        fmt.Println("Positive number")
    }
}
ai24.09.2023

Perplexity AI

TIL about Perplexity AI! It’s pretty slick and useful for web development and research 😊.

TIL that css var can accept a fallback! If we’re setting the variable with some JS and this JS code for some reason or another fails to run, we can set a sensible fallback and present our users with at least something adjacent to what we wanted😊!

color: var(--someVariable, #888888);

Check it out

The acquisition of knowledge brings about satisfaction, but it’s application brings about fulfillment.

every on the JavaScript Array object is great since it checks to see if a given callback function is true for every value in the array… but there’s some caveats to it. Namely, every will return true for the empty array, and it does not take into consideration empty slots during its processing.

Refer to the following code to get an understanding of the caveats:

const isNumber = (v) => typeof v === 'number'

[].every(isNumber) // true
[1, ,2].every(isNumber) // true
[1, null, 2].every(isNumber) // false

TIL that there is CSS scroll driven animations. They don’t have great browser support (still experimental) but I’m using it on my site 🤣.

TIL that Leondard Davinci was the illegitimate son of a notary and a prostitute 😯!

TIL that commonjs has a require cache. Basically, if you require a module once in the file, it gets cached and if you attempt to require the module a second time, EVEN IF THE CONTENT HAS CHANGED, you’ll get the cached version.

Usually this isn’t a problem but it bit me in the butt when I moved my remix app over to be using express. I had to call this function inside of my server code when remix finished rebundling.

function clearRequireCache() {
	Object.keys(require.cache).forEach(function (key) {
		delete require.cache[key]
	})
}

Today I learned about Typescript execute (I’m using it on my website now too 😆). It’s a CLI alternative to node for running Typescript & ESM!

Check it out

ai06.07.2023

AgentGPT

My coworker told me about AgentGPT. It’ll be super helpful with things like Code Assistance and Email and Communication.

js28.06.2023

shadcn

Check out Shadcn to learn more about re-usable components built using Radix UI and Tailwind CSS! It’s not a component library; you copy pasta the code you need into your project 😛!

There’s a new kid on the block and this new kid is a game changer! Panda is a new css-in-js solution that works in the server-first framework era!

I was googling around and saw that there was a plugin created to allow me to use chatgpt inside of neovim! I just downloaded it and I got to say, it is quite nice 😊!

neovim and chatgpt together

So I switched over to neovim as my editor quite a while ago but to be honest, I’ve had a hard time grasping how to use telescope and ripgrep effectively. Thank god I have chatgpt around to help me figure out and explain basic commands!

There’s a theory that for a signal to be honest, it has to be costly, otherwise everybody could imitate it. It’s why we spend a 1/4 of our salary on an engagement ring (that and being duped by the diamond companies) 😆.

Amor fati is a Latin phrase that may be translated as “love of fate” or “love of one’s fate”. This stoic concept mirrors similar philosophies such as Taqdeer in Arabic, loosley translated as the absolute decree of the Divine or Chardi Kala in Sikhism.

While working on my site, I realized that there was a nifty utility that handles merging my tailwind classes for me!

On NPM

Check it out; thank me later! Gotta love my besties!

Check it out

So I’ve been trying to add in some cache-control headers to my remix site and I’m using cloudflare as my CDN.

In order to determine if the cache is being hit, cloudflare adds a cf-cache-status header to the response. You can find out more about it in the below blog post!

Check it out

Heading to Paris with a friend group soon and our research revealed that we should say Bonjour to folks as we encounter them in our travels. Stark contrast to Vancouver where no one says anything to anyone 🤣.

golang12.04.2023

wails.io

At a recent go meetup, I learned about a a cool thing to create cross platform applications in Go: wails.

Check it out

While working through my webpack config at work, I noticed the usage of @loadable/component. It’s similar to React.Lazy but solves the issue of SSR (which is a requirement for my work’s platform).

Check it out

TIL that there’s a nifty methd on the Object type in JS: fromEntries. It’s the counterpart of entries method that exists on the Object.

Here’s an example for you:

let obj = { foo: 'bar', baz: 42 }
const entries = Object.entries(obj)
console.log(entries)
// Expected output: [["foo", "bar"], ["baz", 42]]

obj = {}
console.log(obj)
// Expected output: {} 😆

obj = Object.fromEntries(entries)
console.log(obj)
// Expected output: Object { foo: "bar", baz: 42 }

While working through my golang course, I came across a tool for live-reloading golang apps: Air

Check it out

travel05.04.2023

wanderlog

A few good friends and I are going on a trip to Europe. Sheelz (one of my besties), found this awesome app to help us with planning our itinerary.

Check it out

js14.12.2022

Fusejs 🔥

As I was thinking about how I would migrate my search index for my site to remix, I came across an alternative to Lunrjs… and yes I know I can use Algolia but I personally think it’s overkill for what I want for my site.

Check it out

js07.12.2022

unifiedjs

So there’s this thing called unified that allows us to take things like Markdown, HTML, or plain text and turns it into structured data (AST) so that we can apply transformations on said data. Its rich plugin pipeline allows us to typically write one line of code to chain a feature into a process.

It’s more than this though as it is collective that spans multiple organizations and an ecosystem that includes:

  • remark
  • rehype
  • retext
  • redot

Check it out

TIL that there’s a fieldset element in HTML that allows for grouping of several elements in a web form.

Check it out

This technology has been around for a while (> 3 years) and I haven’t used it personally, but it’s pretty damn slick. IndexedDB is a low-level API for client side storage. Its more popular brother, localStorage has its limitations and if you’re ever running into them, you might want to take a look at IndexedDB. In a nutshell, IndexedDB is a transactional database system that allows us to permanently store data inside a user’s browser. It would be useful for applications that store a large amount of data and applications that don’t need persistent internet connectivity to function.

Keep these key things in mind:

  • It stores key-value pairs.
  • It’s built on a transactional database model.
  • The API is mostly async.
  • It’s object-oriented 😲.
  • It’s not SQL
  • It adheres to the same origin policy.

TIL that there’s a sick new css feature dropping soon: container queries. I haven’t played around with them much myself but based on what I’ve seen, they allow developers to now not only make layout changes via css based on the viewport but also based on the size of an elements containining element.

A lot of people are pretty hyped about this feature and calling it the next evolution of responsive design on the web.

Check it out

It’s that time of the year again where we’ll be forking over some of our hard earned cash to retailers in preparation for the holidays. TIL camelcamelcamel exists and keeps pricing history of all amazon products.

Whenever you see a “sale” being listed on Amazon, make sure to check this site first 😊!

I haven’t used this yet and today I didn’t have much going on as I had to work on some stuff around the house (renovations and all) but there’s a project that tries to make it a little bit more ergonomic to work with tailwind and React 😊.

So I’ve been going pretty hard on my neovim settings and trying to really embrace the command line when doing any sort of development work. Today I learned about something called lazygit which is a terminal gui for git.

After being laid off from Productboard, I’ve been spending time thinking about how I want to continue with my career and what to do with my spare time. Of course landing a job is my priority, but during my time off, I want to devote time to learning skills and technology that I’ve never been able to make the time for in the past.

One thing I’ve always wanted to do (for the “by the way factor”) was setting up vim for my local development work. I devoted the entire day today to set up my neovim config; I’m pretty happy with it so far.

Here’s the config

js17.10.2022

DomMatrix

I was once asked about matrices in an interview. Still unsure how they work but we’ve got them in the browser specs 🤣.

Check it out

js11.10.2022

matchMedia

My mind was blown today when I learned that browsers now ship with a native way to easily check if the window matches a specific media query. 🤯

Essentially, you can pass in a media query into window.matchMedia and the returned object will tell you if the window matches you media query. It also ships with event listeners so you can handle resizing out of the box ❤️ .

Shout out to my main man Vepor for this piece of knowledge!

Check it out

TypeScript has a handy utility type to extract types from a union type 🤭.

type MyUnion = 'Hello' | 'Mom' | 'I' | 'Love' | 'You'
type WithoutMom = Extract<MyUnion, 'Mom'>
// the above will be the type "Hello" | "I" | "Love" | "You"

TLDR; this property, when applied to an html element will make it so that the element ignores user input (this also applies to screen readers).

Check it out

Turns out (at least at the time of writing this TIL), that react doesn’t include the code property on their Synthetic Events.

So if you wanna figure out which commit in a repo caused an issue, git has a useful command to do just that.

git bisect

Check it out…

Turns out there’s a way to improve event listeners that are tied to the scrolling event in the browser.

const onScroll = (e) => console.log('sup', e)
window.addEventListener('scroll', onScroll, { passive: true })

This will make it so that our scroll handler will not block the main thread (yay!).

Check it out

Intelligence is knowing a tomato is a fruit. Wisdom is knowing you don’t put a tomato in a fruit salad. Charisma is convincing everyone that it’s a salsa.

Brought to you by Christine.

There’s been a lot of new developments in the space of package bundlers. From the OG Webpack to, Rollup to the new kid on the block esbuild each of them have their own unique set of features.

esbuild offers better build times as it is written in Go, which is compiled to JavaScript. The tradeoff here is that es5 isn’t supported (but that’s okay if you’re not supporting IE11). It’s pretty awesome but as it’s in active development and fairly new, it’s not as widely used as the other bundlers and therefore doesn’t have the rich plugin resource that somethings like webpack has.

However, you can leverage esbuild and plug it into a webpack config and via esbuild-loader I did this at work today and it helped with devserver startup times and greatly improved the production build times.

There’s a reason why React is moving toward a linked list approach and moving away the recursive approach used in the current reconciler.

Recursion requires an O(n) call stack (causes jank). But if you do things iteratively, you can stop relying on stacks and push all object references into the heap. Arguably this is harder to reason about and harder to understand but the perf gains are totally worth it.

So there’s this really handy web api that allows you to create a lightweight version of a Document and append nodes to said lightweight Document. The beauty with this is you can create this tree, make changes to it, and then all at once append the lightweight tree to the DOM.

This is much better than continually writing to the DOM and causing a shit ton of reflows.

Check it out

random01.07.2021

Recursion

Never forget, recursion occurs when a thing is defined in terms of itself.

YOU CAN HAVE ITERATION INSIDE OF A RECURSIVE FUNCTION.

Iteration and recursion aren’t mutually exclusive.

It’s normal to sit down with a few negative feelings about beginning your work. It’s how you handle those feelings that matters.

Turns out you can set up auto scroll restoration with browser APIs (yay!).

Check it out

Learned about another way to traverse a tree! It’s called Post-Order.

Essentially:

  1. Go left as far as you can
  2. Go right as far as you can
  3. Visit Node

All you need to keep in mind for a GET vs a POST. Basically, POST bodies are not limited whereas the GET values are limited by a character limit for the value.

Get and Post

TIL that there’s a TS utility type that does the opposite of Partial.

Check it out

Want to make it so that people need to provide some sort of generic argument if they don’t use some predefined defaults for your TS code. Check this out:

type NoInfer<T> = [T][T extends any ? 0 : never]

type QT<T> = 'first' | 'second' | T
type Yolo<T> = {
	data: QT<T>
}

function doSomething<T = void>(args: Yolo<NoInfer<T>>): null {
	// do something
	return null
}

doSomething({ data: 'first' }) // okay
doSomething({ data: 'three' }) // not okay
doSomething<'three'>({ data: 'three' }) //okay

State management is hard but there’s a difference between state management in our apps versus managing our app’s server cache. Luckily, there are two libraries that we can use to help us with our server side state needs.

React query and RTK Query. We’re using React Query at work but RTK query looks cool too!

I’ll probably do a small POC this weekend to get a feel for the ergonomics.

Whenever you’re going to be talking about dates, keep these things in mind:

  1. Formatting (locale)
  2. Timezone (this dictates how much time to add based on UTC)
  3. UTC (know what this is)

There’s a nifty little library to write shell scripts using node. Yay for less hassle!

Check it out

Turns out that there’s a neat little time formatter that most browsers ship with that allows us to do locale specific time formatting. It’s inside of the Intl.

Intl.DateTimeFormat('en-US').format(Date.now())

Check it out…

Turns out Carl Sagan was a big proponent of Marijuana. Who knew lolz.

Lol so I got a stye and a home remedy that I’ve been using is a tea bag.

You steep the tea bag for one minute and when it’s bearable, rest the teabag on the affected eye for 5-10 minutes. Preferably use black tea.

Alright, so I’ve been writing TS for a while and was never really sure why we needed these .d.ts files… until today.

The purpose of these files is so that authors/the community can backport popular JS libraries with TS type definitions. This allows library authors the freedom to keep on writing their JS code but allows users of TS to benefit with working code and the typings they need.

These typings probably exist in something like Definitely Typed. However, at work, we’re using a mix of JS and TS (JS is for the jest setup code) and therefore we were required to have ambient TS files so that our TS test code could benefit from the typings related to our JS files.

We are using module aliasing for our TestUtils so that we can do things like import { render } from 'TestUtils'. Under the hood, the render function is just a nicely wrapped render function from react-testing-library and so the return types are the same. There was a bug where if I tried to import the RenderResult from the testing library, VS code’s TS language server would yell at me for having an undefined module. The following code highlights the fix/issue.

working.d.ts
// TYPESCRIPT IS A PAIN
// https://stackoverflow.com/questions/39040108/import-class-in-definition-file-d-ts/51114250#51114251
declare module "TestUtils" {
  export function render(
    v: any,
    other?: { initialState?: any }
  ): import("@testing-library/react").RenderResult
}
not-working.d.ts
// doesn't work
import { RenderResult } from "@testing-library/react"

declare module "TestUtils" {
  export function render(v: any, other?: { initialState?: any }): RenderResult
}

If you want to know what element on the page currently has focus, you can use document.activeElement to get access to the reference of the currently focused element.

I’m using it to handle the / key to force my website to move focus onto the search input (similar to what github does) and to not try to make the site refocus the search if is the currently active element.

React.FC was more meant to help beginners get more comfortable writing React components with TS but honestly, the cons of using it (always having the ability to pass children to your component even though you might not be rendering said children) make me want to not use it.

If you’re wanting to type children, you can do:

type Props = {
	children?: React.ReactNode
}

Turns out TS has some conditional types!

T extends U ? X : Y

If T extends U, then T is type X otherwise it is type Y.

Check it out

There’s a neat little utility type in TypeScript that lets you reach into a function and discern the types of the function arguments.

Parameters<(s: string) => void>
// [s: string]

Check it out

css23.03.2021

attr

There’s a neat little css function that lets you retrieve the value of an attribute of the selected element and use it in the stylesheet!

For example:

<h1 data-color="red">Hello</h1>
h1 {
	color: attr(data-color);
}

Would generate an h1 with red text!

Check it out

So turns out there’s a handy screen that react-testing-library exports. Don’t always have to use the container!

While working my way through The Pragmatic Programmer I came by a tip that really struck a chord with me. Good design is easier to change than bad design.

Make things easier to change. Why is decoupling good? By isolating concerns, we make each easier to change. Why is the single responsibility principle good? A change in requirements is mirrored by a change in one module.

If you’ve created too large of a hole inside of your drywall and you want to reuse the same hole for perhaps a drywall anchor, using spackle as filling won’t be enough.

Use wood filler; this’ll give you the consistency and strength you need for loadbearing purposes in the drywall.

So I’ve seen this pattern around but didn’t know it had a name! If you’ve ever used Context in React, you’re aware of there being a Provider and a Consumer and those two are namespaced to a specific Context. Keep in mind, this is assuming you’re using React < 16.8.0.

I’m still trying to figure out when this should be used.

namespace-pattern.js
const SomeContext = React.createContext()

const SomeContextProvider = ({children}) => {
  const [yolo, setYolo] = React.useState(false)

  // highlight-next-line
  return <SomeContext.Provider>{children}</SomeContext.Provider>
}

const SomeContextConsumer = ({children}) => {
  return (
    // highlight-next-line
    <SomeContext.Consumer>
      {context => {
        if (context === undefined)
          throw new Error('Must be used within a SomeContextProvider')

        return children(context)
      }}
    </SomeContext.Consumer>
  )
}

So if you have an element positioned absolutely in a container and the container has overflow hidden the absolute element is gonna be hidden.

Need a structure of grandparent (relative position) > parent (overflow hidden) > child (position absolute)

Check it out

Bruh, you can’t do something like document.querySelector('#1') and expect it to work. The browser will yell at you! You have to do document.querySelector([id='1'])

Check it out

Turns out header values are always strings. So if there’s a header value like x-header and you want to see if it is true or false in JS, doing Boolean(req.header[‘x-header’]) would be true regardless because “true” and “false” are both true for Boolean constructor.

You can do something like req.header[‘x-header’] === ‘true’

So lol when I was exporting an SVG from Affinity, I noticed that the svg size was around 3 mb. Reducing the art board size made the export size waaaay better.

Turns out we aren’t forced to be shackled to the Adobe suite 🤣. There’s similar software called Affinity that does pretty much what Adobe does (without the arm and leg payment).

Check it out

TIL that vscode has region folding! It’s like this:

//#region
const y = () => {}
const x = () => {}
//#endregion

Check it out

Not really a TIL but more of a reminder to myself to not forget about the damn concept of closure and to leverage it in Scala. Just because you have one function to handle sorting, doesn’t mean that function can’t have some helper functions defined within its body.

Turns out you can have a contenteditable attribute on your html and that’ll make (you guessed it), your content editable lol.

…go ahead… try it out on the list below… you know you want to. 🤪

  • Food
  • Food
  • Food

So today at work I noticed that I was not getting the spacing I expected from block level elements. The reason this was occuring was because my team and I were relying on margins for spacing out elements, but we should have been relying on padding instead.

Margins collapse in on each other (for siblings). If element A has a margin bottom and element b is its sibling and underneath and has a margin top, we would see the margin bottom of element A “collapse” (not be applied) and only see the margin top of element B.

Check it out

TIL that printer ink requires a vehicle (a resin like honey) and a pigment (a powder). There’s a lot that goes into this process and it is pretty damn cool.

How’s it made

TIL that there are credit card scams around like skimmers and shimmers that oftentimes show up at gas station pumps and other brick-and-mortar shops.

To avoid being a victim, do not pay at the pump if they require you to insert the card at the pump (these pumps can be tampered with whilst the inside card reader most likely will not be). Pay with tap when you can

Also, don’t forget to check your transactions regularly and check out free credit reporting services like Borrowell.

So Scala is a single inheritance language but allows classes to utilize multiple traits (these are like interfaces in Java). Traits and Abstract classes in Scala are essentially the same but there are some key differences.

  1. Traits cannot have constructor parameters (you can’t do a new trait)
  2. A class can inherit from multiple traits.
  3. Traits are for behaviors. Abstract classes are for things.

toFixed(n) provides n length after the decimal point; toPrecision(x) provides x total length. Both will round! Both are functions that exist on the Number prototype!

There’s so much to learn and more than enough time! Here are some cool links to check out.

js30.11.2020

volta

While working on a javascript monorepos course, I was exposed to Volta.

Volta eases the node development process by allowing developers to easily pin node versions to a project and will automatically switch the development machine to the right version when switching between contexts 😃.

TIL keyboard shorcut for emojis on a mac is: Command-Control-Space

TIL that there is a cache control header for a shared cache. The s-max-age is similar to the max-age in that they both set a timer to invalidate a cache for a particular resource. The difference between the two is that the s-max-age applies to shared content and therefore applies to content on a CDN.

This is better in circumstances where we want to force an invalidation for a particular resource. This is not possible with max-age.

TIL that there’s a dope resort spot in South Asia. Maldives.

js16.11.2020

npm i prefix

So you can actually run an npm install for a directory without having to actually change directories. Look: npm install --prefix /my/project/root

There’s a Netlify Identity Widget (that is framework agnostic) which can be leveraged to add some authentication to web apps deployed to Netlify.

There’s a limit of 1000 people but for a small e-commerce business that’s more than enough.

Here it is

js12.11.2020

react-window

If you’re rendering over 50 rows in react-table and messing around with complicated filter logic, it’s wise to utilize something like react-window to get some performance gains as users are not going to be interacting with elements not in the viewport so we shouldn’t tax them for the rendering costs behind such frivolous elements.

TIL that there is a method built into the Date object toLocaleString. It essentially allows us convert a date string to a locale specific string.

Check it out

99% of the time you want to be using useEffect but there are some rare use cases for useLayoutEffect and I incidentally ran into one today at work 😂.

  • useLayoutEffect if you need to mutate the DOM and/or perform some measurements
  • useEffect if you don’t interact with the DOM at all.

Pattern matching in Scala allows us to do some very nifty things. This is all possible due to the fact that the comparison of objects is not done at the reference level but at the value level.

Refer to the TIL regarding Scala’s case classes😁.

case class Cat(color: String, food: String)

val oswald = Cat("black", "Chips")

object ChipShop {
  def willServe(c: Cat): Boolean = {
    c match {
      case Cat(_, "Chips") => true //don't care about the first argument
      case Cat(_, _) => false // don't care about any arguments (this is the default case essentially)
    }
  }
}

ChipShop.willServe(oswald) // true

A pattern can be one of

  1. a name, binding any value to that name;
  2. an underscore, matching any value and ignoring it;
  3. a literal, matching the value the literal denotes; or
  4. a constructor-style pattern for a case class.

For Scala’s case classes we get a sensible == operator which is different from Java’s—it delegates to equals rather than comparing values on reference identity.

Soooo.

new Person("Noel", "Welsh") == new Person("Noel", "Welsh")
// res4: Boolean = true

Scala case classes are the bread and butter of Scala data types! Learn them ye fool.

The syntax is as normal but with a case prefix. By using the case word before class, Scala provides us some functionality out of the box, including but not limited to:

  1. the ability to omit the val keyword in constructor calls. (A field for each constructor argument)
  2. a nicer toString method for classes
  3. a sensible equals which operates on the field values of an object
  4. a copy method that creates a new object with the same field values as the current one
case class Cat(color: String, food: String)

// vs

class Cat(val color: String, val food: String)

TIL that you can’t open a window in full screen with window.open

Check it out

While making my way through a new React course, I learned that React elements have a $$typeof property to help mitigate issues with XSS attacks.

In essence, the $$typeof prevents anyone from trying to get React to create invalid elements via JSON. Even if a user passed in some JSON that mimicked what a React Node looks like, the value of $$typeof is a Symbol and this cannot be mocked by JSON!

Check it out

While I was working on something at my day job, I learned about

prex.

It essentially allows us to cancel our promises (think axios or some other xhr).

token-example
return new Promise<void>((resolve, reject) => {
      const request = http.get(from);

      // abort the request if canceled.
      const registration = token.register(() => {
          request.abort();
          reject(new Error("Operation canceled."));
      });

      request.on("error", err => {
          registration.unregister();
          reject(err);
      });
}

TIL it’s better to apply for a limit increase on a line of credit (LOC) if there’s a legitimate reason that this increase is required. Regardless of the approval of the LOC increase, one’s credit score takes a hit so it makes sense to try and increase one’s odds of being approved.

Having a reason for a limit increase (like a home reno) is more likely to get approved than someone who just wants some more backup funds.

Whenever you’re talking about setting up a business or a new venture, it’s important to start with why. Start with why, then move to how, and then move to what… it might be worth reading this book:

Start With Why

Basically, avoid having to do any major logic from the SIGTERM signal or any other EXIT signals in node because they can often times be fired twice. It’s much better to run any clean up code that you want in the start of the process versus the end.

Also check out death on npm. It’s a handy helper library.

While working through my functional programming course, I encountered a fun little leet code exercise. It’s fucking computer science so I’m not even surprised I had to solve a problem like this -.-

Anyway, here’s how the pascal triangle code will work in JS and in Scala

js-example
function run() {
  for (let row = 0; row <= 10; row++) {
    const rec = []
    for (let col = 0; col <= row; col++) {
      rec.push(pascal(col, row))
    }
    console.log(rec)
  }
}

const pascal = (col, row) => {
  if (col === 0 || row < 1 || col === row) return 1
  else return pascal(col, row - 1) + pascal(col - 1, row - 1)
}

run()
scala-example
def main(args: Array[String]): Unit = {
  println("Pascal's Triangle")
  for (row <- 0 to 10) {
    for (col <- 0 to row)
      print(s"${pascal(col, row)} ")
    println()
  }
}

/**
  * Exercise 1
  */
def pascal(c: Int, r: Int): Int = {
  // base case is if c = 0, just 1
  if (c == 0 || r < 2 || c == r) 1
  else pascal(c, r -1) + pascal(c - 1, r - 1)
}

Turns out you can’t use Xpaths to access elements in a shadow dom.

Don’t use xpaths

Encapsulation in the web is hard (especially when it comes to CSS)… thank god for the Shadow DOM.

The Shadow DOM allows us the ability to keep the markup structure, styling, and behavior (JS) so that different parts of the application do not clash. This is entirely important for a micro frontend architecture — we do not want style clashing.

My colleague Danny and I were able to utilize the Shadow DOM and Single SPA to create an encapsulated navbar. 😁

Shadow

Check it out about it here

My friend Anil showed me an awesome breakfast recipe that incorporates grape tomatoes and ricotta cheese (both things I hardly eat…until now 😼)

Check it out

js06.08.2020

console.info

TIL that Jest will buffer console.log statements but this is not true for console.info.

js05.08.2020

lodash fp

TIL that lodash-fp was merged into lodash but there are some discrepancies. For example, compose is flow and they both have curry.

Be proactive! Stay ready so you don’t have to get ready 😁

Express middleware is broken up into different types based on the number of arguments your middleware function takes. A middleware function that takes 4 arguments is classified as “error handling middleware”, and will only get called if an error occurs.

Check out supertest when you’re doing api development :)

Ever run into the problem of having your __tests__ directory sitting outside of your src causing issues with TypeScript? I’m a big fan of colocating tests but if you’re ever working on a codebase that doesn’t embrace this philosophy and instead has a __tests__ directory that sits at the same level as src, you may need a a separate tsconfig for your tests.

This is possible thanks to the -p flag in TS and the fact that we can extend tsconfig files. For the project in question, we used:

  1. tsconfig.json
  2. tsconfig.build.json
  3. tsconfig.test.json

Check it out

Risk is the dancing partner of reward.

Struggling is not failing. Struggling is succeeding on not giving up.

Don’t be a sucka! TIL that you can get free HTTPS on your server thanks to a handy tool called Certbot.

Suck on that people who tried to charge me for HTTPS.

TIL during a basic async node training video, that the node core api exposes promisified (I think that’s a word) functions. For example fs provides a promise based API.

Check it out

TIL that input of type of “checkbox” is not an html element that can receive a read-only attribute. 😖

Check it out

My colleague Danny taught me how to easily create exportable interfaces for react components.

Rather than exporting interfaces in a component (imperatively), you can set up a typings.d.ts inside of a directory and it will be available to all components that reside in subdirectories. 😁

GeneralComponent
|--> GeneralComponent.tsx
|--> typings.d.ts
|--> Specialized // has access to interfaces in typings
     |---> Specialized.tsx
     |---> __tests__

Another valid way to do things is split typings in this way.

src/types
|--> canvas.d.ts
|--> interfaces.d.ts

After a brief conversation with Darnell, TIL that a controller should only be concerned with the processing of a request. Database logic etc. should live in the Model.

I’m such a noob 😆

This technically isn’t something that I learned “today” but it is something that I wanted to make note of! If you’re ever working on a project and need to support internationalization, your library of choice— assuming you’re writing in React— should be react-i18next!

Why? My coworker Vincent wrote up a great ADR (Architectural Decision Record) and evaluated the library and some of the benefits it totes is…

  1. It has a hooks implementation so there’s no change needed to be made to the render portion (the view) of your React components.
  2. It generates translation files in a directory that can be easily handed off to a translator to populate
  3. There’s enterprise options available if ye need em!

Vincent and I learned that if you’re attempting to add keyboard events to divs, you’ll want to supply a role and a tab-index if you’re wanting to react 😉.

During work today, my colleague Mo and I were having issues making DELETE requests to a micro service that he had created. In Postman and the standard XHR function that ships with Google Chrome, the delete requests were going through with no problem but when we tried to make a call via axios.delete(url/id), the server kept returning a 400 error.

The truly peculiar thing was that making a call in the following manner worked:

axios({
	method: 'DELETE',
	url: `url/${id}`,
	headers: {
		'Content-Type': 'application/json',
		Authorization: 'Bearer SOME_TOKEN',
	},
})

However, this failed:

axios.delete(`url/${id}`, {
	headers: {
		'Content-Type': 'application/json',
		Authorization: 'Bearer SOME_TOKEN',
	},
})

Long story short, TIL: axios.delete will drop the content-type header (which is the right behavior) so my buddy Mo had to change up his micro service endpoint to not expect a content type 😁!

My girl taught me about the California stop; it’s essentially the same thing as a rolling stop but cooler sounding.

I’ve always believed wholeheartedly in the following quote,

A fool will learn nothing from a wise man. But a wise man will learn much from a fool.

Yesterday evening, I was approached by a visibly homeless woman and amidst her musings about how Canada is a flawed nation where people are left to suffer as corporate greed consumes the very essence of the city and about how one doesn’t necessarily need a highschool education to be intelligent, she dropped a nugget of wisdom on me that I’ll carry with me for quite some time.

According to this woman, and I googled this after to make sure that it was in fact true, the people of Denmark actively assisted in helping Jewish Danes escape from Hitler by evacuating them to neutral Sweden.

By no means am I saying that this woman is a fool; please don’t misunderstand me. What I’m trying to hit home with this TIL is that wisdom can come from anywhere, whether it’s a college professor or a homeless woman who, and I can’t make this up, began urinating in her pants mid conversation… everyone has got something to offer.

Long story short, t tiers of ec2 instances are spotty and unreliable; stick to using m series at the very least

The focus-within pseduo class represents an element that has received focus or contains an element that has received focus.

/* Selects a <div> when one of its descendants is focused */
div:focus-within {
	background: cyan;
}

Check it out

Single sign-on (SSO) is a property of access control of multiple related, yet indepdent records. Thanks to this property, users can log in with a single ID and password to gain access to any of several related systems.

If you’re working in a corporate setting, this is how you’re able to seamlessly switch between applications (maybe in the browser) and not have to log in despite the fact that all these systems have some sort of authentication and authorization piece associated with them.

Check it out about it here!

TIL that the main attribute in package.json refers to the entry point for a commonjs node module and that the module attribute refers to the es module that can be used by bundlers such as wepback and rollup.

Check it out

The title sums it up but to learn more about it, visit this link

A neat little concept that I learned about (just briefly) today is this idea of inversion of control. Essentially, assuming that we’re talking about React/Vue components, instead of having a mega component that accepts several different props to handle various things like position, aligment, etc, it sometimes make more sense to have a component that inverts control to the caller.

This means that we can extract out our business logic to a base component and then have specialized components that utilize the inversion of control to create a huge combination of different specializations/configurations. For exampe, we could have a Base Accordion that implements some core business logic and the rendering/extending can be left to a specialized implementation like Left aligned accordion or All can open acccordion.

The benefits of this pattern are the following:

  1. We no longer have to ship unncessary code to users — people only get the code that’s relevant to their use case
  2. Our bundle sizes will drop considerabley because of number 1
  3. We don’t fall victim to the “it’s only one more if statement” trap… if someone wants to extend our base component we expose the API’S they need to easily do this.

Thanks to Kent for the blog post!

I’ll be honest, up until today, I never really cared about character encodings and didn’t ever bother to learn anything about them… what a huge mistake! Character encodings are the unsung heroes that allow us to display languages (besides English) reliabely on computer systems.

The gist of UTF-8 is that it is an encoding that allows us to take Unicode code and map said codes to meaningful linguinstic representations. Codes that are between 0 and 127 occupy 8 bits — a single byte — and then any codes above this upper bound can use up to 6 bytes. The beauty of this system is that strings encoded in UTF-8 look exactly the same as strings encoded in ASCII. Americans are chilling and don’t need to worry about squat, while the rest of the world has to “jump through hoops” to make sure that they’re alphhabet will work across computer systems.

Check it out

So here is a nice little thing I’m going to try and get people using at work, I hope! PLOP js!

It allows us to keep our project structure consistent by creating a CLI tool that will help automate the creation of files that should exist for various modules in our codebase. For example, if we are creating a React component, a structure that we’d like to enforce in order to keep our project neat and tidy is:

  1. componentName > file name
  2. componentName > index.js
  3. componentName > __tests__

When it comes to managing npm packages for your organization, there’ a great little package called: Verdaccio. Verdaccio is a light-weight npm proxy registry. It allows us to host private Node.js packages and is compatible with all client package managers, such as Yarn and npm. There’s even a Docker image you can use to get you up and running!

A headless UI component is a component that offers up maximum flexibility by providing no interface itself! This sounds like a radical idea but for library authors, it’s a great pattern to provide their users with all that sweet sweet functionality that they’re craving without any of the bloat/stylystic decisions that come with interface decisions.

This pattern works great when the logic of a component is complex and can be decoupled from its visual representation.

From a React perspective, this can be acheived via an HOC, render props, or if you’re using React > 16.8, hooks. Below is an example of two different interface implementation of a very simple toggle — the state isn’t complicated but since we created this headless interface, the UI can easily be changed/edited and does not suffer from the opinions of the library author!

The Example

renderProps
class Toggle extends React.Component {
  state = {
    on: false,
  }

  handleClick = (cb = () => {}) => evt => {
    this.setState({ on: !this.state.on }, () => cb(evt))
  }

  render() {
    const { state, handleClick } = this
    return this.props.children({ state, handleClick })
  }
}

function CheckBox() {
  return (
    <Toggle>
      {({ state, handleClick }) => {
        return (
          <input
            type="checkbox"
            id="scales"
            name="scales"
            checked={state.on}
            onChange={handleClick()}
          />
        )
      }}
    </Toggle>
  )
}

// Just some simple styled components
// to illustrate how we can decouple the styling from the logic
const Label = styled.label``
const Input = styled.input``
const Slider = styled.span``

function PrettyToggle() {
  return (
    <Toggle>
      {({ state, handleClick }) => {
        const appliedHandleClick = handleClick(console.log)
        return (
          <Label>
            <Input
              type="checkbox"
              checked={state.on}
              onChange={appliedHandleClick}
            />
            <Slider />
          </Label>
        )
      }}
    </Toggle>
  )
}
hooks
function useToggle(cb = () => {}) {
  const [on, updateClick] = React.useState(false)
  const event = React.useRef()

  React.useEffect(() => {
    cb(event)
  }, [on])

  return {
    on,
    handleClick(evt) {
      event.current = evt
      updateClick(!on)
    },
  }
}

function HookPrettyToggle() {
  const { on, handleClick } = useToggle(console.log)

  return (
    <label class="switch">
      <input type="checkbox" checked={on} onChange={handleClick} />
      <span class="slider round"></span>
    </label>
  )
}

function HookCheckBox() {
  const { on, handleClick } = useToggle()

  return (
    <input
      type="checkbox"
      id="scales"
      name="scales"
      checked={on}
      onChange={handleClick}
    />
  )
}

In the Rest maturity model, Hypermedia is considered to be the most mature — the highest level.

  1. The swamp of Pox (XML)
  2. Resources
  3. HTTP Verbs
  4. Hypermedia

In a nutshell, Hypermedia has REST endpoints expose links to other related data. For instance, if there was an endpoint that existed to fetch all the products in a particular catalog, each product resource in the payload would have a _links property that had attributes that would allow users of the API via self to navigate to the respected product. Just by visiting products, I’d have a way of getting to a specific product without having to store the API endpoint in my source code; the initial API call would prove it to me.

products.json
{
  "_embedded": {
    "products": [
      {
        "title": "Navy blue stone wash jeans",
        "seller": "Revtown Jeans",
        "_links": {
          "self": {
            "href": "/products/42"
          }
        }
      }
      // more products ...
    ]
  }
}

Check it out

Node is super useful for doing high throughput low latency I/O tasks! Here’s a diagram that roughly describes how Node works (I omitted libuv but you can bet it’s there):

Server/A machine                                               World/Another machine
+-----------------------------------------------+              +-------------+
| +-------------+                               |              |             |
| |JS           |                               |              |             |
| |             |                               +-------------->             |
| |             |                               |              |             |
| |             |                               |              |             |
| |             |                               |              +-----+-------+
| +---+--^------+                               |                    |
|     |  |                                      |                    |
|     |  |                                      |                    |
|     |  |                                      |                    |
|     |  |                                      |                    |
|     |  |                                      |                    |
|  +--v--+------------+  +------------------+   |                    |
|  |Node (C++)        |  |OSS               |   |                    |
|  |                  |  |                  |   |                    |
|  |                  <--+                  |   |                    |
|  |                  +-->                  |   |                    |
|  |                  |  |                  |   |<-------------------+
|  |                  |  |                  |   |
|  +------------------+  +------------------+   |
|                                               |
+-----------------------------------------------+

When making a request to a server, if they aren’t accepting OPTIONS requests, you’re going to have a bad time. Axios and Fetch make preflight requests by default so if you want to circumvent this, you’ll have to use the vanilla XHR capabilities.

Turns out a spade is also a suit for cards and a type of shovel! 😱.

There is no such thing as “potato seeds”… it’s just a “seed potato”! That is… there are only potatoes in this world 😱.

The unload event that is available to us web developers isn’t consistent across browsers (but we already know that many things arent 😂). Really, if you want to have predictable behavior and need to fire off some event/code when a user leaves/closes your page, you should be listening to a page visbility change.

Check it out

Buddy works allows us to create pipelines for our projects! Similar to how envoyer and deploybot works!
It comes with a bunch of prebuilt recipes for when you try to set up your actions. We’re using it to do deployments to a project site after PRs are merged and firing off notifications on slack!

Check it out

If you want your code to be tested, make it easy to test!
If you want people to do the right thing, make the right thing the easy thing!
When people get lazy, we can’t rely on discipline — make the lazy thing the right thing!