Today I Learned

A Hashrocket project

List Top-Level NPM Dependencies

The npm ls command can be used to list all dependencies for a project. This will, however, produce an exhaustive list of all dependencies including dependencies of dependencies. A list this large probably isn’t going to be of much use.

The --depth flag allows you to restrict the depth of the dependency tree that is generated.

$ npm ls --depth=0

This will produce a list of only the top-level dependencies.

See man npm-ls for more details.

Destructure Variables As Props To A Component

When passing down props, a redundant-feeling pattern can sometimes emerge.

const MyComponent = ({ handleChange, handleBlur }) => {
  return (
      <OtherComponent />
      <MySubComponent handleChange={handleChange} handleBlur={handleBlur} />

The typing feel duplicative, as if there ought to be a better way. One option is to simply pass down all the props:

<MySubComponent {...props} />

This approach may result in passing down props that we don’t intend to pass down and clutters the flow of data in our app.

Here is another approach:

const MyComponent = ({ handleChange, handleBlur }) => {
  return (
      <OtherComponent />
      <MySubComponent {...{handleChange, handleBlur}} />

Here we are taking advantage of two ES6 features. Since the naming is the same, we can use property shorthands. Then we immediately use the spread operator to splat it back out as the props to the component.

h/t Vidal Ekechukwu

🔑 Set foreign keys to null

Sometimes, in certain circumstances, it is reasonable to have a foreign key value of null.

ActiveRecord’s .has_many method has an argument to set the foreign key column on referencing rows to null when that record is deleted.

dependent: :nullify


class Post < ApplicationRecord
  belongs_to :author
  belongs_to :category

class Category < ApplicationRecord
  has_many :posts, dependent: :nullify

In this example whenever a category is deleted, any posts referencing the categories table will have their foreign key set to null.


Defining Variants With Constructor Arguments

In Helping The Compiler Help Us With Variants, I introduced the concept of variants with a basic example of how to define and use one. The fun doesn’t stop there.

We can take variants a step further by defining them with constructor arguments.

type listActions =
  | Length
  | Nth(int);

The second variant is defined such that it is paired with some extra data — a single int argument.

Here is how we use that variant in our code:

let performListAction = (l: list(int), action: listActions) => {
  switch(action) {
  | Length => List.length(l)
  | Nth(n) => List.nth(l, n)

performListAction([7,8,9], Nth(1)); /* 8 */
performListAction([1,2,3], Length); /* 3 */

Our switch statement not only matches on that variant, but it makes the int argument available as a value we can consume in that step of the switch.

source code

Helping The Compiler Help Us With Variants

ReasonML gives us something called a variant which is similar to what other language call enums and union types. By defining a variant, we give the compiler some information about exactly what values a variable can take on — its allowed variants.

Here we define the kinds of roles that users in our system can have as well as a user type for representing individual users:

type userType =
  | Student
  | Teacher
  | Admin;

type user = { role: userType, id: int };

And here is how we might use it in some authorization code:

let canCreateClasses(u: user) {
  switch(u.role) {
  | Student => false
  | Teacher => true

We’ve neglected to include Admin in our switch statement. The compiler will inform us of this with a warning.

this pattern-matching is not exhaustive. Here is an example of a value that is not matched: Admin

source code

Pipe text into Vim from stdin

You can pipe text into vim directly from stdin. This can be helpful if you want to edit the output of a long bash command, or if you want to see what an installation script contains before piping it into bash.

curl -fsSL | vim -

The key is to use the - after the vim command to make it read from stdin. This will open a new buffer with the output of the previous command.

Postgres automatically appends timezone

Dates can be notoriously hard, particularly when it comes to timezones.

If you select a date without timezone information and cast it to a data type w/timezone, Postgres will assume the timezone of the server:

select '2000-01-01'::timestamptz;
│      timestamptz       │
│ 2000-01-01 00:00:00-06 │

I’m located in CST hence the -06 at the end of the time specification (6 hours before UTC time).

To use a specific timezone such as UTC, instead of your server’s timezone which can be pretty arbitrary:

select '2000-01-01'::timestamptz at time zone 'UTC';
│      timezone       │
│ 2000-01-01 06:00:00 │

Postgres now displays the time in UTC. Still probably not what you expected (6am?) - Postgres infers the 00:00:00 time in your timezone and converts it to UTC (in my case adding 6 hours).

So how would you get it to show 00:00:00 and still be in UTC timezone?

select '2000-01-01 00:00:00 UTC'::timestamptz at time zone 'UTC';
│      timezone       │
│ 2000-01-01 00:00:00 │

If you use timezone aware data types it is recommended to always specify the timezone when inserting data, otherwise you are in for a world of trouble.

Quick syntax reference for #SQL directly in #psql

Whenever I forget the syntax for a certain SQL command in Posgres I usually reach for Dash or simply search DuckDuckGo for the the specific command. That usually yields the Postgres official documentation website which is great…

Wouldn’t it be nice though if I could stay right inside psql and get the documentation I am looking for?

It would.. and it’s possible:

\h create index

create index screenshot

Use \h followed by the SQL command - this is not the full verbose documentation that you would find on the Postgres docs website but it’s more of a syntax reference - which is most of the time what you need.

If you are not sure what to type or simply want to explore new commands try typing \h without anything after it - you will see something like this:

slash h by itself screenshot

autocmd on a List of Extensions

Yesterday I was VimScripting and learned that the autocmd function can execute against multiple file extensions in a single line of setup. Here’s a contrived example:

" ~/.vimrc
autocmd BufWritePost *.exs,*.ex :! git add %

In this code, after every buffer write on files matching .ex and .exs, add the current buffer to our Git staging area. Learning this helped me reduce duplication in my configuration.

Inline Component Styles With Reason React

If you’ve written much React.js, the following may look familiar:

<span style={{
  width: "10px",
  height: "10px",
  backgroundColor: "rgb(200, 64, 128)"
}} />

This is how we do inline styles with JSX in JavaScript.

When it comes to doing inline styles with JSX in our ReasonML code, the best approach for now is to use a make function for styles provided by the React DOM bindings.

<span style=(
    ~backgroundColor="rgb(200, 64, 128)",


New Dates Can Take Out Of Bounds Values

You can create a new date by feeding it arguments for year, month, and day.

> new Date(2017, 11, 31)
Sun Dec 31 2017 00:00:00 GMT-0600 (CST)

What happens if we push the day value out of bounds?

> new Date(2017, 11, 32)
Mon Jan 01 2018 00:00:00 GMT-0600 (CST)

It rolls over to the next month.

Does the same happen when we push the month value out of bounds?

> new Date(2017, 12, 31)
Wed Jan 31 2018 00:00:00 GMT-0600 (CST)


What about negative values?

> new Date(2018, -1, 31)
Sun Dec 31 2017 00:00:00 GMT-0600 (CST)

It rolls the month, and consequently the year, back.

Show All Pivotal Stories With Blockers

Within the past year Pivotal Tracker added a feature that allows you to mark stories with blockers. These are visual indicators with a description that are used to show a particular story is blocked, that is, it cannot be completed until something else is taken care of.

In order to maintain the health of the project, it is good to triage these blocked stories from time to time. The best way to identify all of the blocked stories is to filter them into their own column.

Enter is:blocked into the search bar to show all of the blocked stories.

Run A Hardware Check On A Mac

If your Mac is behaving in an odd way, there may be an issue with some piece of the hardware — such as the RAM.

You can perform a hardware check in order to chase down a diagnosis.

  • Shutdown your machine
  • Boot your machine
  • While it is booting, hold down the d key

At this point, the machine should have booted into a special hardware check mode. Select your preferred language, the hardware check will be performed, and any issues will be reported.

h/t Dillon Hafer

Quickly Bootstrap A React App Using Reason

The ReasonML language and ecosystem is great for developing React apps. As you might expect from the React community, there is a set of reason-scripts for a ReasonML/React project which works similarly to the standard create-react-app scripts.

First, you need to install the BuckleScript platform and this must be done using npm.

$ npm install -g bs-platform

From there, it is a matter of using the yarn create command to generate a React app that uses the aforementioned reason-scripts.

$ yarn create react-app my-reason-react-app --scripts-version reason-scripts

Next steps from here are documented in the and should be familiar to anyone who has used create-react-app in the past.

Multi-Argument Functions As Syntactic Sugar

When writing a multi-argument function, like the following adder function:

let adder = (x, y) => x + y;

adder(2, 3); /* => 5 */

We are utilizing a syntactic sugar of the function syntax. The same function can be written as such:

let adder = (x) => (y) => x + y;

adder(2, 3); /* => 5 */

As you can see, we can apply the function in the same way.

This is useful because it means we can partially apply (or curry) our functions to create other functions.

let adder = (x, y) => x + y;
let twoAdder = adder(2);

twoAdder(5); /* => 7 */

source code

Alpha channel in hex colors #RRGGBBAA

In the past if I’ve needed to give a hex color an opactiy I would use the opacity attribute, like this:

div {
  background-color: #cecece;
  opacity: 0.5;

But as of Chrome 62/Firefox 49/CSS Color Module Level 4 you can now include the alpha channel information into the hex code:

div {
  background-color: #cecece88;

And if you are using the shortened version of the hex color it looks like this:

div { 
  background-color: #ccc8;

Check out the MDN Docs

Exhaustive Pattern Matching Of List Variants

ReasonML’s switch expression allows for powerful pattern matching. When using switch to pattern match against a list, the compiler will be sure to warn you if you haven’t accounted for all variants of a list.

let getFirst = (numList: list(int)): int => {
  switch(numList) {
  | [first,] => first

this pattern-matching is not exhaustive. Here is an example of a value that is not matched: []

The compiler knows that a list can either be 1) empty ([]) or 2) contain at least one value and another list ([a,]). To ensure all variants are accounted for, we can include the [] case in our switch.

let getFirst = (numList: list(int)): int => {
  switch(numList) {
  | [] => -1
  | [first,] => first

source code

String Interpolation With Integers And Sprintf

ReasonML’s Printf module comes with a number of functions for formatting values of various types. The sprintf function allows for string interpolation.

let red = 64;
let green = 256;
let blue = 128;
let alpha = 1;

let color =
  Printf.sprintf("rbga(%i, %i, %i, %i)", red, green, blue, alpha);


It functions the same as fprintf but instead of outputting the result to some channel, it returns a string. It enforces type checking as well — the %i is specifically for integers, so using that with a type other than an integer will result in a compilation error.

See the Printf docs for more details.

source code

Pattern Matching On Exceptions

ReasonML supports powerful pattern matching through the switch statement. This even includes pattern matching against exceptions that may arise as a way of catching and handling those exceptions.

let values: list(int) = [1,3,5,7,9];

let getValue = (list, index) => {
  switch (List.nth(values, index)) {
  | value => value
  | exception Failure("nth") => 0
  | exception Invalid_argument("List.nth") => 0

getValue(values, 0); /* 1 */
getValue(values, 1); /* 3 */
getValue(values, 5); /* 0 */
getValue(values, -1); /* 0 */

The List.nth docs detail what happens in the two kinds of out of bounds scenarios that would raise an error — Failure and Invalid_argument. You can pattern match against those by declaring the respective cases as exception instances and then returning the desired values in response.

source code

Waiting On Multiple Promises

You may find yourself in a situation where you have to request multiple resources from multiple API endpoints and then combine that data in some way.

One way to achieve this would be with nested promises.

fetch('/blogs').then((response) => {
  let blogs = response.body;

  fetch('/tags').then((response) => {
    let tags = response.body;

    // combine blogs and tags ...

This nesting isn’t ideal and it can get hard to read as the full implementation is put into place.

The Promise API provides an alternative.

let blogsPromise = fetch('/blogs')
let tagsPromise = fetch('/tags')

Promise.all([blogsPromise, tagsPromise]).then(([blogsResp, tagsResp]) => {
  // combine blogs and tags ...

With Promise.all() we are able to wrap any number of promises and wait for all of them to resolve until we do something with the results. This allows us to create a context in which we have all the data we need without a bunch of nesting.

Execute Remote Commands with SSH

Today I switched workstations. As a Vim user this means copying some local dotfiles around, appending a few here, deleting a few there. It was a good reminder that executing remote commands is part of SSH.

Here’s how I’ve been appending old custom configurations on my old workstation, to others’ already existing (shared) configurations on the new machine. The quoted command is executed on the remote machine:

$ ssh jake@oldworkstation "cat ~/.vimrc.local" >> ~/.vimrc.local

Toggle Between Terminals In VSCode

VSCode allows you to have multiple terminal tabs, but you have to manually switch between them with a drop down. For me, that is a lot of mouse action. I’d prefer to have a keyboard shortcut that allows me to switch between them. Fortunately, there are commands for going to the next and previous terminal which can be attached to keybindings.

Try adding the following two entries to your keybindings.json file:

  { "key": "cmd+shift+k", "command": "workbench.action.terminal.focusNext" },
  { "key": "cmd+shift+j", "command": "workbench.action.terminal.focusPrevious" },

Save the file and then start toggling between your different VSCode terminals.


Firefox DevTools Vim Mode

I’ve been using Firefox more and more lately, and keep discovering new features with the devtools. One of the most handy when trying to edit css or html is vim mode.

To enable vim mode in the devtools, first to to your about:config page:

Change the devtools.editor.keymap setting to vim and you get all your familiar editing functionality.

List The Available JDKs

Want to know what JDK versions are installed and available on your machine? There is a command for that.

$ /usr/libexec/java_home -V
Matching Java Virtual Machines (3):
    9.0.4, x86_64:      "Java SE 9.0.4" /Library/Java/JavaVirtualMachines/jdk-9.0.4.jdk/Contents/Home
    1.8.0_162, x86_64:  "Java SE 8"     /Library/Java/JavaVirtualMachines/jdk1.8.0_162.jdk/Contents/Home
    1.8.0_161, x86_64:  "Java SE 8"     /Library/Java/JavaVirtualMachines/jdk1.8.0_161.jdk/Contents/Home


The listed VMs show what JDK versions you have and the final line shows which is currently the default version.

Generate Absolute File Path In Ruby

Pass a string to File.expand_path to generate the path to that file or directory. Relative paths will reference your current working directory, and paths prepended with ~ will use the owner’s home directory.

=> "/Users/avogel/My/Working/Directory/example.rb"

=> "/Users/avogel/example.rb"

Show List Of Most Recently Committed Branches

The standard way to list your branches is with the git branch command. If you use branches extensively for feature work and bug fixes, you may find yourself overwhelmed by the list of branches trying to visually parse through them for the one that you had worked on recently.

With the git for-each-ref command, we can produce a better list of branches.

$ git for-each-ref --sort=-committerdate --count=10 --format='%(refname:short)' refs/heads/

The command itself will iterate over all of the repository’s refs and print them out as a list. The --sort=-committerdate option will ensure that list is sorted by refs mostly recently committed to. The --count=10 option limits the list output to 10 refs. The format flag cleans up the output a bit, only showing the shortname of the ref. Lastly, the refs/heads/ argument ensures that only local refs are included in the output, thus ignoring remote refs.

The result is a list of local branches ordered by recency which generally corresponds to relevance.

See man git-for-each-ref for more details.


Alter The Display Name Of A React Component

Components adopt their display name from the class or function that renders them. A component’s display name becomes important to know about as soon as you start digging through the React devtools interface — whether debugging or just perusing the component hierarchy, the display names of components is what you’ll see. In most circumstances, the display name is good enough as is. If you want or need to, you can change it.

const Hello = ({ name }) => {
  return (
Hello.displayName = "Hola";

By setting the displayName property on this component, you are able to alter what name is used by React devtools.

This can be useful when bringing in a 3rd party library or component that doesn’t use a display name that you find helpful — in particular when using Higher Order Components.

List Tmux Keys

Want to see all the mapped shortcuts for your Tmux session? Try this, assuming a Tmux leader of <CRTL-Z>:

<CTRL-Z> ?

This produces a list like the following:

bind-key    -T prefix       :                 command-prompt
bind-key    -T prefix       ;                 last-pane
bind-key    -T prefix       =                 choose-buffer
bind-key    -T prefix       ?                 list-keys
bind-key    -T prefix       D                 choose-client

Visually Select A React Element For Inspection

Similar to the Elements tab of Chrome devtools, the React devtools extension provides a visual element selector to make it easier to inspect an element you can see in the browser.

select and inspect a react component

Open the React devtools, click the crosshair icon, hover around the browser until the element you are looking for is visually highlighted, and then click. The React component hierarchy will be expanded to reveal that element. You can now inspect it or quickly navigate to nearby elements.

Defining State In A Simple Class Component

Most class components start off with a constructor which does some initialization of the component including setting the components initial state. It might look something like the following:

class MyComponent extends React.Component {
  constructor(props) {
    this.state = {
      loading: true

  render() {
    if (this.state.loading) {
      return (
    } else {
      // ...

If setting state is the only thing you need to do in the constructor, then you can skip the constructor all together.

class MyComponent extends React.Component {
  state = {
    loading: true

  render() {
    if (this.state.loading) {
      return (
    } else {
      // ...

This second example will work the same as the first, and it is a bit more concise.

Forward Multiple Ports Over SSH

I sometimes find myself doing web app development on another machine via an SSH connection. If I have the server running on port 3000, then I like to use SSH’s port forwarding feature so that I can access localhost:3000 on my physical machine.

$ ssh -L 3000:localhost:3000

What if I have two different servers running? I’d like to port forward both of them — that way I can access both.

SSH allows you to forward as many ports as you need. The trick is to specify a -L for each.

$ ssh -L 3000:localhost:3000 -L 9009:localhost:9009

Use A Ref To Autofocus An Input

When creating highly interactive interfaces with React, we are trying to make the user’s experience of our app as smooth as possible. This means that when an edit button reveals an input field, we want that field to be in focus so that the user can immediately start typing.

This is a great use for React’s ref prop. When you supply your component with a function as the ref prop, that function will be called with a reference to itself on mount and with null on unmount.

class MyAutofocusInput extends React.Component {
  focusInput = (component) => {
    if (component) {

  render() {
    return (

When this component gets rendered, the input will be focused via our focusInput function.

Note: refs only work with class components, so don’t try to use it with a functional component.

See Refs and the DOM in React’s documentation for more details.

Phoenix Select Form Helper

The select form helper allows you to easily add a select input to your forms.

= form_for @changeset, resource_path(@conn, :create), fn f ->
  = select f, :book_id, @books
  = submit "Save Post", class: "btn"

Among the types of arguments that the select helper can accept are two-item tuples. The first item in the tuple is used as the label for the option and the second item is used as the value for the option.

Media.list_books returns a list of structs representing all of the books in the database. We’ll need to get from a list of structs to a list of tuples.

To do that, we’ll pipe the list of Book structs to and use an anonymous function to generate two-value tuples from those structs.

def new(conn, _params)
  books =
      |>{"#{&1.title} by #{&}", &})

  render conn, "new.html", changeset: changeset, books: books

Quickly Search For A Component With React DevTools

As the size of your React app grows, it can become challenging to track down specific components within the React DevTools extension. You opened it up with the hopes of quickly inspecting the props being received by a component, but find yourself navigating through the DOM structure instead.

The React DevTools extension provides a search bar that can be used to quickly filter out most components.

react devtools component search

The search bar is located at the top of the extension. Once you start typing the results are immediate. Then, if you hover over any of the remaining components, you’ll get some visual feedback as they are highlighted in the browser.

Span a grid item across the entire css grid

When using css grid you might want an item to span item to span across the entire grid even when that grid has many columns.

Grid with many columns looks like this:

.grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);

You could certainly just use grid-column: span 5 but if the number of columns changes then you aren’t going across the entire screen. To span a grid item across the entire css grid regardless of number of columns use the / operator and the index of the last column -1:

.item {
  grid-column: 1 / -1;

Dispatch Anywhere With Redux

Your React app is going to have a single top-level store which is connected to the app with the Provider component. Most of the time, when you create a connected component, you’ll create prop functions that dispatch on a redux action.

This isn’t the only place you can dispatch though.

If you export your store, then it can be imported anywhere along with its dispatch function.

// src/index.js
export const store = createStore(rootReducer);
// src/components/MyComponent.js
import { store } from '../index';
import { updateData } from '../actions';

// ...

  componentDidMount() {
    getData().then((json) => {

See the dispatch documentation for more details.

Chrome DevTools Audit Panel

One highlight of the Chrome 63 update was the addition of four new audits to DevTools.

‘Audits’ are one of the many DevTools panels lurking in the background, waiting to make your application better; I hadn’t noticed them until today. They will analyze and provide a downloadable report on your application’s Progressiveness, performance, accessibility, and best practices.

‘Today I Learned’ scored 91 out of 100 on accessibilty. That’s something I’d like to improve, and this panel could help direct that journey.

Aliasing an Elixir Module Within Itself

I was attempting to compile a Phoenix application and I got this error:

Post.__struct__/0 is undefined, cannot expand struct Post

The issue was in a function I defined in the module.

def changeset(%Post{}= post, attrs \\ %{}) do

I assumed that you would get references to a module within said module for free. That’s not the case. There are two ways to fix the error. One is to use the full module name in the parameter list.

def changeset(%Forum.Post{}= post, attrs \\ %{}) do

Alternatively, I can alias the module within itself.

alias Forum.Post

Netrw header toggling with vim-vinegar

vim-vinegar is a vim plugin that “cleans up” Netrw as-

an attempt to mitigate the need for more disruptive “project drawer” style plugins

but it turns off the Netrw header, which, while unnecessary is the second most charming feature of vim.

To reclaim your Netrw header, use I while in Netrw.

As a vim-vinegar bonus, use - while in a buffer to open Netrw in the directory of the current buffer.

Having rapid directory access available changes everything

All quotes are from the the vim-vinegar README. Thank you to Vidal for the hat tip about I.

Get the mime-type of a file

The file command for both Linux and Mac can provide mime information with the -I flag.

> file -I cool_song.aif
cool_song.aif: audio/x-aiff; charset=binary

There are longer flags to limit this information, --mime-type and --mime-encoding.

> file --mime-type cool_song.aif
cool_song.aif: audio/x-aiff
> file --mime-type cool_song.aif
cool_song.aif: binary

And if you are using this information in a script you can remove the prepended file name with the -b flag.

> file --mime-type -b cool_song.aif
> file --mime-type -b cool_song.aif

Combine -b and -I for a quick terse mime information command

> file -bI cool_song.aif
audio/x-aiff; charset=binary

Pure Data's netreceive uses special protocol

Pure Data is graphical programming language specialising in audio applications. It has an object called netreceive that is a socket (either TCP or UDP) that accepts a connection and outputs messages sent to it.

There are 2 gotcha’s that I experienced in working with it.

The first. It requires a special protocol, called FUDI. Each message must be terminated by a semicolon ;. The message can contain any number of ‘atoms’ (strings) separated by whitespace but the semicolon is essential.

The second. The documentation of pure data contains running examples, if you open the documentation of netreceive before running the object in your patch, you will get a bind: Address already in use (48) error. Close the documentation and try again!

Fold A Visual Selection And Expand It Back

If I visually select a series of lines — say the open and close tags of a large div in an HTML file I am reading through — and then hit zf, it will be folded into a single line. That line will list how many lines are included in the fold as well as the content of the first line of the fold.

If I later come back to that fold and want to expand it again, I can hit zd to delete (or undo) the fold.

To do this, you’ll want to make sure your foldmethod is set to manual. This can be done by running the following command:

:set foldmethod=manual

See the vim helpfiles (:h fold) for more details.