Today I Learned

A Hashrocket project

113 posts about #javascript

Get The Location And Size Of An Element

All modern browsers ship with the getBoundingClientRrect() function. It can be invoked for any DOM element. It returns the x and y coordinates of the element within the browser viewport as well as the height and width values and the top and bottom values along the y-axis and left and right values along the x-axis.

> $0.getBoundingClientRect()
  "x": 381.421875,
  "y": 70,
  "width": 1030.578125,
  "height": 48,
  "top": 70,
  "right": 1412,
  "bottom": 118,
  "left": 381.421875

For instance, this is the result of invoking it against a header element on the MDN page linked above.

Download/Upload Redux Store In Chrome DevTools

People explaining the value of Redux as a JS state solution often point out that it’s designed to support great developer tools. Today I got a better understanding of what that means.

Chrome DevTools currently includes the toolbar shown below. The upload and download buttons, fourth and third from right, allow you to download, inspect (and edit), and upload the Redux store as a JSON file.

This is seems like a fantastic way to debug situations that might be difficult to reproduce through user interactions.

Spread The Rest With ES6

The spread operator provided by ES6 is a powerful syntactic feature. One way it can be used is to capture the rest of an object or array in a variable.

const pokemon = ["Charmander", "Squirtle", "Bulbasaur"];
const [first,] = pokemon;

console.log("Remaining: ", rest); // Remaining: ["Squirtle", "Bulbasaur"]

const gymLeaders = {
  brock: "rock",
  misty: "water",
  surge: "electric",
  erika: "rainbow"
let { brock, erika, ...otherLeaders } = gymLeaders;

console.log(otherLeaders); // Object {misty: "water", surge: "electric"}

Using this spread destructuring we can capture the remaining parts of an array or object in a variable. We can also use this syntax in a function signature to grab specific items from an incoming object argument without losing track of the rest — this is especially useful in React.js development when dealing with incoming props.

This is a stage 3 feature and may not be available in your particular environment.

See a live example here.

Custom Type Checking Error Messages With Yup

In Yup Schemas Are Validated Asynchronously, I showed how to create a simple schema that allows you to enforce that a value is a number.

const numSchema = yup.number();

If we use this schema to validate something that isn’t a number, Yup will provide a lengthy default message. Here is what we get if we validate against 'hey':

this must be a number type, but the final value was: NaN (cast from the value "hey").

This value isn’t necessarily suitable for displaying to a user. We can customize the type checking error message by redefining our schema with the typeError() function:

const numSchema = yup.number().typeError("Invalid number");

Yup Schemas Are Validated Asynchronously

Yup provides a flexible object schema validation DSL. For instance, if you want to enforce that a certain value is a number, you can define something like this:

const numSchema = yup.number();

You can then validate anything against that schema.

const validator = (val) => {
    .then(result => {
      console.log(result); // it is the value of `val`
      return true;
    .catch(error => {
      console.log(error.errors); // array of validation error messages
      return false;

The validation is async, so if it succeeds the then block is hit. If the validation fails, it will fall through to the catch.

validator(5) // => true
validator('what') // => false

Promises and then function return values

The return type of Promise function will dictate how future chained then functions behave. If you return a Promise then the next chained then function will execute when the Promise that you returned is resolved.

  then(() => {return Promise.resolve('bar')}).
  then((v) => console.log(v))

// prints bar

If you return something different from the then function, then the argument of the next chained then function will be the previous returned value.

  then(() => {return 'baz'}).
  then((v) => console.log(v))

// prints baz

Check out the MDN docs for Promise.prototype.then

H/T Brian Dunn

H/T Josh Branchaud

Link A JavaScript Package Locally

If you are putting together a JavaScript package and you’d like to test it out locally before putting it on NPM, use npm link.

First, from the directory of the package you are creating run:

$ npm link

This will symlink the package to the global node modules directory.

Then, from the base project directory that you want to try importing and using the package from, run:

$ npm link name-of-package

This will create an additional symlink from the global node modules directory to the node_modules of this target project.

You’ll now have access to the project, try an import to get what you need and try it out.

See man npm-link for more details.

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.

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.

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.

Import All Exports As Object

Here’s a technique for importing constants from a file:

import * as routes from './routes'

This wraps all the exports from routes.js in the object routes. We can access any of those constants like this:

<Route path={routes.exportedPath} />

I like this technique for this use case, because it keeps our import to one line and adds a meaningful namespace.

Fill An Input With A Ton Of Text

I needed to test out a form validation for an input that should render an error when the length of the context exceeds 10,000 characters. Two small tricks make this easy.

First, you can target any DOM element via the Chrome dev tools by selecting it and then referencing it via the $0 magic variable. More details here.

> $0

Second, you can quickly and precisely generate a very long string with the repeat function.

> "a".repeat(10000)

Combine these two tricks in the browser to fill the input with a ton of text:

> $0.value = "a".repeat(10000)

h/t Dillon Hafer

ISO-8601 Formatted Dates Are Interpreted As UTC

Using new Date() or Date.parse() with a string that represents a date is a great way to create a Date object for a specified date. A variety of formats are accepted by these methods.

But, caution!

There are subtle differences in how those dates will be interpreted. Given any old string that reasonably represents a date, the date will be interpreted using the local time zone, in my case CST.

> new Date('2017-12-4')
Mon Dec 04 2017 00:00:00 GMT-0600 (CST)

However, as soon as we use an ISO-8601 compliant date format, ECMAScript 5 specifies that the date ought to be interpreted using the UTC time zone. As you can see, the results are drastic enough to affect what day it comes out to.

> new Date('2017-12-04')
Sun Dec 03 2017 18:00:00 GMT-0600 (CST)


Destructuring The Rest Of An Array

ES6 offers some amount of pattern matching on arrays. This means you can do fun stuff like grabbing a couple values and then destructuring the rest of the array into a variable.

> const kids = ["Mike", "Will", "Dustin", "Lucas", "Eleven", "Max"];
> const [first, second,] = kids;
> first
> second
> rest
["Dustin", "Lucas", "Eleven", "Max"]

By using the ... syntax with a variable name in the left-hand side of the assignment, you are able to capture an array of whatever isn’t assigned to preceding variables.

Use Decorators for React Higher Order Components

When working with React libraries that make use of higher order components, you wrap your component in a function:

import { withRouter } from 'react-router-dom';

class MyComponent extends Component {

export default withRouter(MyComponent)

When chaining through multiple HOC’s, this can become unwieldly:

import { withRouter } from 'react-router-dom';
import { connect } from 'react-redux';

class MyComponent extends Component {

function mapStateToProps(state) { ... };

export default withRouter(connect(mapStateToProps)(MyComponent));

But there is hope, with the decorator syntax in ES6/Babel you can make this look a bit cleaner:

import { withRouter } from 'react-router-dom';
import { connect } from 'react-redux';

function mapStateToProps(state) { ... };

export default class MyComponent extends Component {

Full documentation here.

Alternate names in destructuring assignment

Want to use destructuring assignment, but don’t like the names of the variables as they exist in the object?

If you have data like this:

const optimus = { name: 'Optimus', type: 'Semi-Truck' };
const bumblebee = { name: 'Bumblebee', type: 'Small Car' };

Instead of creating customized variables like this:

const { name, type } = bumblebee;
const bumblebeeName = name;
const bumblebeeType = type;

You can express this type of destructuring in one line like:

const { name: optimusName, type: optimusType } = optimus;

Freeze An Object, Sorta

You can freeze a JavaScript object using Object.freeze which will help enforce some immutability practices. Don’t be fooled though, you can still modify arrays and objects in the frozen object.

Here is what the docs have to say:

The Object.freeze() method freezes an object: that is, prevents new properties from being added to it; prevents existing properties from being removed; and prevents existing properties, or their enumerability, configurability, or writability, from being changed, it also prevents the prototype from being changed.

And here is Object.freeze in action:

> const things = {one: "two", hello: "world", cats: ["Von Neumann", "Sosa"]}
> Object.freeze(things)
{one: "two", hello: "world", cats: Array(2)}

> = "three"
> things.dogs = []
> delete things.hello

> things
{one: "two", hello: "world", cats: Array(2)}

> things.cats.push("Sneaky")

> things
{one: "two", hello: "world", cats: Array(3)}

See the MDN Docs for more details.

h/t Jake Worth

Iterating over objects in Lodash

Many of the Lodash collection functions iterate over either an object or an array. Somewhat unintuitively for me, when iterating over objects the first argument of the iteratee function is a value and the second argument is the key.

The documentation for Lodash lists the arguments for the iteratee in the description for each function. For collection functions that generally looks like this

The iteratee is invoked with three arguments:(value, index|key, collection).

By searching through the documentation for index|key you can find all the functions for which this is true.

Using a Lodash function that can return iterate over an object looks like this:

const result ={a: 1, b: 2}, function(value, key) {
  return value + key;

// result is now ["a1", "b2"]

H/T Ryan Messner

`Object.entries` helps you iterate over objects

You may find yourself with an object with lots of entries that you need to transform into an array of extracted information. For examples sake lets say:

  const things = {
    a: 1,
    b: 2

And we need to turn that into and array [2, 3].

We can use Object.entries to turn the object into an array of key/value tuples.

const arr = Object.entries(things)
// arr === [["a", 1], ["b", 2]]

Then we can iterate over that array with map:

const mappedArr = => {
  const [key, value] = tuple;
  return value + 1;
// mappedArr === [2, 3]

Object.entries is an ES7 proposal implemented in Chrome/Firefox/Edge and polyfilled with CoreJS, the polyfill library used by Babel.

Compare Form Values with Yup

We’ve been using yup to validate a JavaScript form, and found ourselves facing a common problem when a user signs up for a service:

How do we ensure a user’s email matches their email confirmation?

yup’s test function helped us find a solution. It’s documented like this:

mixed.test(name: string, message: string, test: function)

test takes a name, a message to show on failure, and a function that returns a boolean. We paired this with the email we get from our parent.

var schema = yup.object().shape({
  email: yup
  emailConfirmation: yup
      'emails do not match', 
       function(emailConfirmation) { 
         return emailConfirmation ===; 

String Interpolation With Template Literals

ES6 adds support for template literals. Template literals make it much easier to compose strings of content — string interpolation. They allow for single and double quotes without having to fuss with escaping. Embedded expressions are also supported which means you can avoid awkward-to-type string concatenation with the + operator.

Here is an example:

> let movie = 'it'
> `What's up, I just saw "${movie.toUpperCase()}".`
"What's up, I just saw "IT"."

Make console.log stand out with custom css style

I know your browser console is full of messages because you are debugging something, and that creates a lot of noise. Now you are adding a new console.log, and you need it to stand out above the rest.

Maybe you are like facebook and just want to warn your users from pasting in code in the browser in social engineering attacks.


To style a console.log message use the %c interpolation and pass it a css style. e.g.

console.log('%c%s', 'color:red;font-size:5em', alert)

In the example above %s means inerpolate the object into the output string.


Compatibility: tested to work on Firefox, Chrome, and Safari.

h/t Dillon Hafer

`requestAnimationFrame` should call itself

This style of animation is useful when you’re making small changes via javascript. When you pass requestAnimationFrame a callback, the callback is called before a browser repaint, or about 60 times a second. To make sure that you’re getting 60 callbacks a second, you must call requestAnimationFrame from within your callback.

function animate() {

This is a recursive function, so without an exit condition, it will recurse infinitely.

H/T Brian Dunn

Tidy your Reducers with `combineReducers()`

Today I learned by necessity the value of the Redux combineReducers(reducers) function.

combineReducers() supports, in a pretty neat way, the crucial Redux task of delegating to reducing functions their own slice of the state.

The documentation example looks like this:

combineReducers({ todos: myTodosReducer, counter: myCounterReducer });

Which we can improve by naming the reducer functions after the state slices they manage, allowing ES6 shorthand notation:

combineReducers({ counter, todos });

This creates a state object like so:

  counter: ...,
  todos: ...,

Upgrading npm when using `asdf` with `reshim`

The version of npm that comes with nodejs when installed with asdf may not be the latest. In my case I had npm 5.3.0 installed and the newest version is 5.4.2. I upgraded npm with npm install -g npm and saw output that made me think everything installed successfully, but when I ran npm -v I still got 5.3.0.

The answer is to use asdf’s reshim command.

> asdf help reshim
asdf reshim <name> <version>    Recreate shims for version of a package

I ran the following command:

> npm -v
> asdf reshim nodejs
> npm -v

And now I have the latest version and everything is great!

Matching Multiple Values In A Switch Statement

Switch statements are a handy way to execute different branches of code based on a value match. This is often what is used in Redux reducers when updating the state in response to certain actions.

But what if you need multiple values to result in the same branch of execution without duplicating the code?

The execution of a switch statement falls through, so after one match, it will continue to try and do subsequent matches if you don’t interrupt the execution with a break or return. Conveniently, this solves our problem of matching multiple values.

switch (action.type) {
  case "UPDATE_NAME":
    let newData = anotherReducer(, action);
    return { ...state, data: newData };
    return state;

See the MDN docs for more details.

Access A Value Logged To The DevTools Console

Did your app just log an object to the dev tools console and you’d like to interact with that object? It’s not straightforward, but you can do it.

Assuming you already have dev tools opened to the console tab, right click on the value that has been logged to the console. Select the Store as Global Variable option. This will re-log the value assigning it to the temp1 variable.

You can now reference that object as temp1 accessing its values and calling functions.

You can even do this with multiple logged values, each subsequent one will be assigned incrementing variable names: temp2, temp3, etc.


Find an npm library from the command line

When looking for a new package to use with npm you can use npm search <string>. This will query npm and return 20 - 25 results that match your search.

> npm search react-router
NAME                      | DESCRIPTION          | AUTHOR          | DATE       | VERSION  | KEYWORDS
react-router              | Declarative routing… | =ryanflorence   | 2017-08-24 |          | react router 
react-router-dom          | DOM bindings for…    | =mjackson…      | 2017-08-24 |          | react router 
react-router-redux        | Ruthlessly simple…   | =jlongster…     | 2017-02-10 |          | react redux r
react-router-native       | React Native…        | =jmurzy…        | 2017-08-24 |          |
react-router-config       | Static route config… | =mjackson…      | 2017-08-24 |          | react router 
react-router-bootstrap    | Integration between… | =monastic.panic… | 2017-04-19 |          | react react-
react-router-scroll       | React Router scroll… | =taion          | 2017-04-10 |          | react react r
react-native-router-flux  | React Native Router… | =aksonov        | 2017-08-23 |          |

There doesn’t seem to be a way to search by date, version or popularity, but if you pass the --long flag you’ll be able to see the entire description. Without the --long flag the results will be truncated to fit onto one line.

Prettier ignore! 💁 #javascript

Prettier is super helpful but sometimes you just want to format things your way if the output of prettier is not very readable.

To solve this, prettier provides a comment that you can put above any “node” in the resulting javascript AST.

For example:

BEFORE (w/ prettier)

const street_number = this.findAddressComponent(
const route = this.findAddressComponent(resultObj, 'route').long_name;
const zip_code = this.findAddressComponent(resultObj, 'postal_code')
const city = this.findAddressComponent(resultObj, 'locality').long_name;
const state = this.findAddressComponent(

The above is a result of prettier formatting and is not very readable or pretty - so I would need to turn it into a single AST node and put the prettier-ignore comment over it:

AFTER (w/ prettier-ignore)

// prettier-ignore
const address = {
  street_number: this.findAddressComponent(resultObj, 'street_number').long_name,
  route: this.findAddressComponent(resultObj, 'route').long_name,
  zip_code: this.findAddressComponent(resultObj, 'postal_code').long_name,
  city: this.findAddressComponent(resultObj, 'locality').long_name,
  state: this.findAddressComponent(resultObj, 'administrative_area_level_1').short_name.toUpperCase(),

Now the address components will be accessible from the address object (e.g. address.route) and while still not the prettiest, it is a lot more readable IMO.

Create Bootstrapped Apps With Yarn

The yarn cli comes with a create command that is a convenience command for generating bootstrapped apps that follow the create-<name>-app convention.

Want to create a React.js app using create-react-app, invoke the following command:

$ yarn create react-app my-app

Don’t already have a particular package globally installed? yarn create will install it for you. For instance, the following command with install and use create-vue-app:

$ yarn create vue-app my-other-app

h/t Gabe Reis

Specify Port Of CRA's Webpack Dev Server

create-react-app gives you a set of scripts, one of which allows you to start a development server that bundles and serves your javascript. This is handled under the hood via webpack-dev-server. By default it attempts to serve from port 3000. If port 3000 is taken it will attempt to connect to another sequential port.

Alternatively, you can just specify the port when starting the development server. This can be done with the PORT env var.

$ PORT=3333 yarn start

Yarn Commands Without The Emojis

If you are a hater and you’d like to run yarn commands without emojis being playfully included in the output, just include the --no-emoji flag. The output of a command like add will look like this:

$ yarn add chalk --no-emoji
yarn add v0.17.10
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...
success Saved lockfile.
success Saved 7 new dependencies.
├─ ansi-styles@3.1.0
├─ chalk@2.0.1
├─ color-convert@1.9.0
├─ color-name@1.1.3
├─ escape-string-regexp@1.0.5
├─ has-flag@2.0.0
└─ supports-color@4.2.0
Done in 0.54s.

See yarn help for details.

Default And Named Exports From The Same Module

ES6 module syntax allows for a single default export and any number of named exports. In fact, you can have both named exports and a default export in the same module.

Here is an example:

// src/animals.js
export default function() {
  console.log('We are all animals!');

export function cat() {

export function dog() {

In this case, you could import the default and named exports like so:

// src/index.js
import animals, { cat, dog } from './animals.js';

animals(); // "We are all animals!"
cat();     // "Meeeow!"
dog();     // "Rufff!"


Run Prettier on all #JavaScript files in a dir

If you are like me you must like formatters such as Prettier which probably prompted you to set your editor to auto format the file on save.

That’s great for new projects but when working on an existing project, every file you touch will have a huge diff in git that can obscure the real changes made to the file.

To solve that you must run prettier on all your javascript files as an independent commit. You can do it with the following command:

find ./src/**/*.js | xargs prettier --write --print-width 80 --single-quote --trailing-comma es5

The flags after the prettier are all my personal preferences except for --write which tells prettier to write the file in place.

Note 1: Make sure you have all the files you are about to change committed to source control so that you can check them out if this did not go well.

Note 2: When committing this change it would be a good idea to use git add -p and go through the changes one by one (which is always a good idea…)

Note 3: To dry run and see which files will be changed run the find ./src/**/*.js by itself. returns wrapped elements

There are thousands of ways to write JavaScript and many ways to map over a collection in JavaScript. The jQuery variant of the function has a couple of peculiarities that might trip you up however.

First, the arguments to the map function are not (item, index) like they are for the function. Instead, they are (index, item).

Second, the jQuery map function does not return an array consisting of the values returned from the map function. It instead returns an array of those values wrapped by jQuery.

This can be unexpected when iterating over a set of elements to create an array of derived values.

Code splitting with Webpack 2 and Babel

Webpack 2 provides the ability to split your code into smaller files that are lazy loaded during runtime as they are needed.

When I first learned about this feature I thought it would be very intelligent in detecting which parts of the code are using a certain module and split all my modules into separate files automatically. That’s not really the case.

If you want to have Webpack split your code and lazy load it you need to explicitly call import in your code. For example:

import Foo from './foo';

class Bar {
  baz() {
    Foo.someMethod(); // this will not be split and lazy loaded
    import('./lazy_module').then(function(lazyModule) {
    }).catch(function(err) {
      console.log('Failed to load lazy module', err);

To have this work you need to install the Syntax Dynamic Import library

Then edit your .babelrc:

  "presets": [["es2015", { "modules": false }]],
  "plugins": ["syntax-dynamic-import"]

The “modules”: false part is really important. It basically instructs Babel to not try and parse the imports but let Webpack 2’s native ability to parse imports to do the work. This was tricky.

There’s more to that and it keeps changing so I recommend visiting this documentation

Yarn global

Just like npm install -g, Yarn provides yarn global add. I found however that it did not work right out of the box to register executable binaries/CLIs.

To fix this add the following to your .zshrc/.bashrc:

# set yarn binaries on path
export PATH="$HOME/.config/yarn/global/node_modules/.bin:$PATH"

Now all binaries installed from yarn should be on your system PATH.

Save disk space with Yarn

Yarn is a fast, reliable and secure replacement for npm. Those are all important attributes in my book for a tool I use daily for development, but that’s not all Yarn offers.

The node_modules directory is often a resource consuming hog both in space and number of files. It is full of junk such as test files, build scripts and example directories.

To clean some of those files Yarn offers the clean command. To run it:

yarn clean

Once run, the command will create a .yarnclean file with patterns of type of files to be deleted. By default yarn clean will delete the following:

# test directories

# asset directories

# examples

# code coverage directories

# build scripts

# configs

# misc

With this file in your project root directory Yarn will ensure to run a cleaning task after every install and report how much space it saved you.

Alias Loaders in webpack

A loader might not be named conveniently for your project. Maybe the path to it is too long and obscures the actual configuration of the loader, in that case you can create an alias with the resolveLoader.alias webpack configuration.

module.exports = {
  module: {
    rules: [
        test: /\.js$/,
        loader: 'smrt',
  resolveLoader: {
    alias: {
      'smrt': require.resolve(__dirname, 'really', 'long', 'path', 'smart-loader.js')

In addition, you may only want to transform one file. Its possible to do that in a require statement and use the bang character (!) prefix syntax to declare the loader like this.

require 'smrt!dumbfile';

Clearly in this case a long loader name would obscure intent.

Export from old school libraries in Webpack

As you are refactoring your legacy Rails project towards webpack and away from the asset pipeline you discovered an old version of the facebook_sdk that is absolutely critical to the ongoing success of the legacy application. This file doesn’t play nicely with CommonJS though and exports its constant with global declarations like:

var FB = {};

This isn’t very global in CommonJS and your app doesn’t have access to that constant anymore.

The problem can be solved with the exports-loader used like so:

module.exports = {
  module: {
    rules: [
        test: /facebook_sdk/,
        loader: 'exports-loader?FB',

This is just a cute way of tacking an export line to the bottom of the file like this:

module.exports = FB;