Today I Learned

ins8s

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) => {
  numSchema.validate(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

Build For A Specific OS and Architecture

Go programs can run anywhere, but you’ve got to create builds specific to each operating system and architecture. This can be done when building by specifying the GOOS and GOARCH environment variables.

For example, if you’d like to build a 32-bit Linux distribution:

GOOS=linux GOARCH=386 go build -o linux_386_build

The GOOS value specifies the operating system as Linux and the GOARCH value of 386 specifies a 32-bit architecture.

The plethora of GOOS and GOARCH options can be found here.

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.

Selecting DOM Elements Faster Than Ever

Selecting and inspecting DOM elements: you’ve done it many times before. Whether you right click the element and select Inspect (which isn’t always all that accurate) or you use the DevTools’ inspect tool with highlight-assist, it takes a couple clicks to get there.

There is a faster way.

Hit Cmd-Shift-C.

Chrome DevTools will be expanded open if it isn’t already and your mouse pointer will be put in inspect mode with the highlight-assist. Find your DOM element, give it a click, and start inspecting!

Toggle Device Mode

Working on some styles? Want to make sure those minor tweaks look good on both desktop and mobile? Your probably moving back and forth between the desktop mode and one of the smaller device modes.

There is a keybinding for this — Cmd-Shift-M

The chrome devtools panel will need to be open and in focus for this to work.

Use withRouter To Pass Down React-Router History

A standard way to navigate with react-router besides using the Link component is to call history.push. Components that are directly rendered by a Route will have access to this and other router props. But what about other components?

The withRouter HOC gives us direct access to a history prop.

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

const SpecialButton = withRouter(({ history, path, text }) => {
  return (
    <Button
      onClick={() => { history.push(path); }}
    >
      {text}
    </Button>
  )
});

This special button component is given the history prop via the withRouter HOC along with any props that we directly pass it. With that we are able to directly invoke a route change using history.push().

Access Go Docs Offline

The Go language has a wonderfully comprehensive standard library. There is documentation for all of it. You can access that documentation anytime if you have an internet connection via https://golang.org/doc/.

If you are without an internet connection, you’re still in luck. Go has a built-in feature for serving the documentation locally offline. Just run the following command:

$ godoc -http=:6060

and then visit localhost:6060.

source

Read Only Input Elements

Here is an input element with a value and no onChange handler.

const MyInput = ({ value }) => {
  return (
    <input value={value} />
  );
};

React will raise a warning regarding the input element because it has a value without an onChange handler leaving React to wonder if it is intended to be a controlled or uncontrolled component.

If our intention is to have the value set but not allow the user to directly change it, we just need to let React know that.

const MyInput = ({ value }) => {
  return (
    <input readOnly value={value} />
  );
};

The readOnly prop means we don’t intend for the input to be modified by user input. The React warning will now go away.

h/t Dillon Hafer

Easier Access To Network Throttling Controls

In Simulating Various Network Connection Speeds, I showed how to change between various simulated connection speeds from the Network tab in Chrome devtools. Unfortunately, the Connection Speed dropdown is crowded out by a number of other controls in the Network tab. As a result, unless that tab is expanded pretty wide, you won’t be able to get at it. I’ve found myself sliding the devtools wider and narrower over and over while testing things with throttling.

There is another, easier place to access throttling.

The console drawer gives us access to a number of additional tabs of controls. Add the Network connections tab for easier access.

Escaping Terminal-Mode In An Nvim Terminal

A recent TIL by Chris Erin showed how to split open a terminal in a Neovim session — :sp term://zsh.

The terminal is emulated into a Vim buffer which means that you can treat it sort of like any other Vim buffer. You start in Normal mode. Once you use any mapping that would transition you into Insert mode, you’ll instead find yourself in Terminal mode. Terminal mode works just like any zsh session (give ls a try).

Try hitting <Esc> though and you’ll see that you stay in Terminal mode instead of being transitioned back to Normal mode.

So how do you get back to Normal mode?

Hit <Ctrl-\><Ctrl-n>.

This is a pretty awkward key mapping though, so follow the Nvim Terminal docs and bring back the Escape key.

:tnoremap <Esc> <C-\><C-n>

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 (
    <div>
      <OtherComponent />
      <MySubComponent handleChange={handleChange} handleBlur={handleBlur} />
    </div>
  )
};

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 (
    <div>
      <OtherComponent />
      <MySubComponent {...{handleChange, handleBlur}} />
    </div>
  )
};

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

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

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=(
  ReactDOMRe.Style.make(
    ~width="10px",
    ~height="10px",
    ~backgroundColor="rgb(200, 64, 128)",
    ())
)/>

source

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)

Yep.

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

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 README.md 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

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, ...rest] => 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, ...rest]). 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, ...rest] => 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);

Js.log(color);

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 Match 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.

Toggle Between Terminals

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.

source

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

/Library/Java/JavaVirtualMachines/jdk-9.0.4.jdk/Contents/Home

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

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.

source

Alter The Display Name Of A 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 (
    <h1>{name}</h1>
  );
};
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.

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) {
    super(props);
    this.state = {
      loading: true
    };
  }

  render() {
    if (this.state.loading) {
      return (
        <p>Loading...</p>
      );
    } 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 (
        <p>Loading...</p>
      );
    } 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 dev@server.com -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 dev@server.com -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) {
      component.focus();
    }
  };

  render() {
    return (
      <input
        ref={this.focusInput}
        value={this.props.value}
        onChange={this.props.onChange}
      />
    );
  }
}

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.

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.

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) => {
      store.dispatch(updateData(json));
    }
  }

See the dispatch documentation for more details.

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.

Inactive And Active Component Styles With Radium

Radium is “toolchain for React component styling” allowing you to do comprehensive inline styling with CSS.

Often times, especially in the case of a series of nav elements, there is a need to style one element as active while styling the rest as inactive. This can be achieved with Radium by defining two groups of styles (base and active) and then relying on props to conditionally apply the active style.

import React from 'react';
import Radium from 'radium';

const styles = {
  base: {
    textDecoration: "none",
    color: "gray",
  },
  active: {
    color: "black",
    backgroundColor: "lightgray",
  },
};

let NavItem = ({ label, path, active }) => {
  return (
    <a
      href={path}
      style={[
        styles.base,
        styles[active && 'active'],
      ]}
    >{label}</a>
  );
};

NavItem = Radium(NavItem);

With Radium, our base (inactive) styles always get applied. Then, the active styles only get applied when the active prop is true. We produce a Radium-ified version of our NavItem on the last line so that Radium can handle all of the styling of the component.

Rendering Multiple Nodes With Fragments

When rendering, React expects a component to only return a single node. The DOM hierarchy of most components will easily follow this rule, but what about those components that do have multiple inline nodes?

The two solutions have been to either wrap the inline nodes in an outer div or to return them as a comma separated array of nodes. With React 16, we can avoid the deficiencies of both of these approaches by using a fragment.

Just wrap your inline nodes with a React.Fragment node. React will understand your JSX without wrapping the output DOM in a superfluous div.

render() {
  return (
    <React.Fragment>
      <p>Name: {firstName} {lastName}</p>
      <p>Email: {email}</p>
      <p>Age: {age}</p>
    </React.Fragment>
  );
}

See the docs on fragments for more details.

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
<input>...</input>

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

> "a".repeat(10000)
"aaaaaaaaaaaaaaaaaaaaaaa..."

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)

Source

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"];
undefined
> const [first, second, ...rest] = kids;
undefined
> first
"Mike"
> second
"Will"
> 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.

Include Some Stats In Your Git Log

A simple git log command is going to give you a concise set of information for each commit. Usually it is enough info. When it’s not, git log can provide additional information with the right flags. To include overall and per-file stats on the number of insertions and deletions, use the --stat flag.

$ git log --stat
commit 66e67741a1cd6857a4467d1453c9f17ef5849f20
Author: c0mpiler <c0mpiler@ins8s.com>
Date:   Mon Nov 13 21:24:41 2017 -0600

    Add Focus The URL Bar as an internet til

 README.md                     |  3 ++-
 internet/focus-the-url-bar.md | 10 ++++++++++
 2 files changed, 12 insertions(+), 1 deletion(-)

commit 9241e3919ef1e4f68b71a1491d368ae6361084aa
Author: c0mpiler <c0mpiler@ins8s.com>
Date:   Sat Nov 11 11:41:40 2017 -0600

    Add Freeze An Object, Sorta as a javascript til

 README.md                            |  3 ++-
 javascript/freeze-an-object-sorta.md | 44 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 46 insertions(+), 1 deletion(-)

...

See man git-log for more details.

Focus The URL Bar

There are a lot of things you can do in the browser without having to reach for the mouse. Bringing the URL bar into focus is one of those things.

Hit Cmd+L in any modern browser (I’ve tried Chrome, Firefox, and Safari) and the URL bar will be brought into focus. From there, you can quickly change the URL of the current tab and your fingers never left the keyboard.

h/t Jake Worth

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"]}
undefined
> Object.freeze(things)
{one: "two", hello: "world", cats: Array(2)}

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

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

> things.cats.push("Sneaky")
3

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

See the MDN Docs for more details.

h/t Jake Worth

Parameterized SCSS Mixins

A mixin can be made to be much more versatile by parameterizing it. If you need variations of a block of CSS, then move the parts that vary out into parameters to the mixin.

@mixin navigation($background-color, $color, $link-color) {
  nav {
    display: flex;
    justify-content: space-around;
    background-color: $background-color;
    color: $color;

    ul {
      list-style: none;

      li a {
        text-decoration: none;
        color: $link-color;
      }
    }
  }
}

div.base-nav {
  @include navgation(#fff, #444, #222);
}

div.admin-nav {
  @include navgation(#000, #fff, #ddd);
}

The mixin can now easily be used to customize different segments of your app’s styling.