Today I Learned

A Hashrocket project

Array concatenation with the spread operator

The spread operator in ES6 javascript is a swiss army knife of wonders. Previously in javascript if you wanted to concatenate two arrays you could use the concat method of an array.

let a = [1, 2, 3]
let b = [4, 5, 6]
a.concat(b) //concat though is not mutative, you have to assign the result
let c = a.concat(b) // we have concatenated

Whether or not Array.prototype.concat is mutative has always been something I get wrong. Some Array methods are mutative some are not! By using the spread operator, I never get this wrong (it’s not mutative).

let c = [...[1, 2, 3], ...[4, 5, 6]]
console.log(c) // [1, 2, 3, 4, 5, 6]

Each line in a Dockerfile is a layer in an image

What has helped me grok docker a bit better is knowing that every line in a Dockerfile has a corresponding hash identifier after the image has been built. Here is a sample Dockerfile:


FROM alpine

RUN echo 'helloworld' > helloworld.txt

CMD ["cat", "helloworld.txt"]

I create the image with:

docker build -t helloworld .

I can now examine each layer in the Dockerfile with docker history helloworld

IMAGE               CREATED             CREATED BY                                      SIZE                COMMENT
1e5d27ca20a8        13 hours ago        /bin/sh -c #(nop)  CMD ["env"]                  0B
84f489011989        13 hours ago        /bin/sh -c echo "Hello World" > helloworld.t…   12B
3fd9065eaf02        2 months ago        /bin/sh -c #(nop)  CMD ["/bin/sh"]              0B
<missing>           2 months ago        /bin/sh -c #(nop) ADD file:093f0723fa46f6cdb…   4.15MB

Three commands and four layers. The FROM alpine command is actually 2 layers that have been squashed together. You can see the <missing> hash for the initial command because it has been squashed into 3fd9065.

The command that creates the helloworld.txt file has a size of 12 bytes because thats the size of the file that was created.

Configuring The Pager

When you run Git commands that produce a bunch of output, Git will use a pager to present the content starting at the beginning, rather than spitting it all out to the screen at once. This will almost always come in handy for commands like git-diff and git-log.

By default, Git uses less as its pager.

You can also choose to configure it to something else by updating your git config file or by running the following command:

$ git config --global core.pager 'more'

If you’d like to turn the pager off altogether, set it to a blank string.

$ git config --global core.pager ''

source

Async/Await UnhandledPromiseRejectionWarning

When an await promise is rejected when using async/await you get an UnhandledPromiseRejectionWarning.

promise13 = () => {
  return new Promise((resolve, reject) => { reject(13)})
}

(async () => {
  let num = await promise13(); // UnhandledPromiseRejectionWarning
  console.log('num', num);
})();

There are two ways to properly handle the promise reject. The first is with a try catch block.

(async () => {
  try {
    let num = await promise13();
    console.log('num', num);
  } catch(e) {
    console.log('Error caught');
  }
})();

The second is by handling the error on the promise itself.

(async () => {
  let num = await promise13().catch((err) => console.log('caught it'));
  console.log('num', num);
})();

Both ways will allow you to avoid the UnhandledPromiseRejectionWarning and also properly handle your rejections. Beware the deprecation message that comes with this warning.

Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Create an NVM Config File

NVM supports a configuration file; the most basic file would declare your Node version of choice. Assuming you’re using that Node version, here’s a foolproof method to create such a file:

$ node -v > .nvmrc

I ran this in a project I’m working on, and it exposed a syntax issue with my .nvmrc; I had initially typed 9.2 instead of v9.2.0, the syntax NVM expects. This command eliminates errors like these.

Building A React App In The Browser

There are a couple relatively new tools that give you just about everything you need to build a React app in the browser.

The first is CodeSandbox. It has a couple pre-configured environments for different technologies. The main one is React. CodeSandbox describes itself as such:

an online editor that helps you create web applications, from prototype to deployment.

The second, which just released out of beta, is Glitch which comes with projects like react-starter so that you can jump into a React project that is ready to roll. Glitch describes itself as:

the friendly community where you’ll build the app of your dreams

You can quickly build and publish React apps in either of these and share them with the world.

Test Coverage Stats With Jest

Jest is a delightful tool for JavaScript testing from Facebook. As your project evolves and you add tests (or perhaps choose to not add tests) you may wonder what kind of test coverage you have. What is the overall coverage? Which files are well covered and which are seriously lacking?

Use the --coverage flag to get this information.

$ jest --coverage

After running all of your tests a table will be output to the terminal with a list of files and their respective coverage percentages in terms of statement, branch, function, and line coverage.

---------------------------|----------|----------|----------|----------|----------------|
File                       |  % Stmts | % Branch |  % Funcs |  % Lines |Uncovered Lines |
---------------------------|----------|----------|----------|----------|----------------|

This can help guide you to what parts of your app may need more testing.

Test Files In create-react-app

Any .js files placed in the __tests__ directory will be treated as tests by Jest when running yarn test. If you don’t want to place all of your files in that directory and especially if you want to co-located your test files with the source files, you can name them with the .test.js or .spec.js suffixes.

Any files in your create-react-app project ending in these suffixes will be treated by Jest as test files and included in test runs.

There are more details in the docs.

xargs substitution

Output piped to xargs will be placed at the end of the command passed to xargs. This can be problematic when we want the output to go in the middle of the command.

> echo "Bravo" | xargs echo "Alpha Charlie"
Alpha Charlie Bravo

xargs has the facility for substituion however. Indicate the symbol or string you would like to replace with the -I flag.

> echo "Bravo" | xargs -I SUB echo "Alpha SUB Charlie"
Alpha Bravo Charlie

You can use the symbol or phrase twice:

> echo "Bravo" | xargs -I SUB echo "Alpha SUB Charlie, SUB"
Alpha Bravo Charlie, Bravo

If xargs is passed two lines, it will call the the command with the substitution twice.

> echo "Bravo\nDelta" | xargs -I SUB echo "Alpha SUB Charlie SUB"
Alpha Bravo Charlie Bravo
Alpha Delta Charlie Delta

Toggle Apps with Redux Stores

Another cool feature of Redux DevTools!

With this tool, we can toggle between any open browser tab with a Redux store, inside the tool:

In this GIF I’m clicking the downward arrow in the upper right. Works the same in Chrome and Firefox.

I’m unsure what problem this solves, but I think it does help promote and educate us about Redux by making other Redux-connected apps easily discoverable via DevTools.

Captured for var in closure can change

Variables can be captured into anonymous functions in go with closures, and its easy to use the variables we declare in a for loop in those anonymous functions, but that doesn’t produce the results I would expect.

var fnArray []func()

for _, chr := range []string{"a", "b", "c"} {
    fmt.Println("Hello,", chr)
    fn := func() {
      fmt.Println("Goodbye,", chr)
    }
    fnArray = append(fnArray, fn)
}

for _, fn := range fnArray {
  fn()
}

The above code outputs:

Hello,a
Hello,b
Hello,c
Goodbye,c
Goodbye,c
Goodbye,c

Go optimizes for loops by using the same memory space for each value that it terates over. To avoid this hard edge you can reassign that value:

capturedChr := chr

Inserted that assignment into our for loop looks like this:

var fnArray []func()

for _, chr := range []string{"a", "b", "c"} {
    capturedChr := chr
    fmt.Println("Hello,", chr)
    fn := func() {
      fmt.Println("Goodbye,", capturedChr)
    }
    fnArray = append(fnArray, fn)
}

for _, fn := range fnArray {
  fn()
}

And produces this more correct output:

Hello,a
Hello,b
Hello,c
Goodbye,a
Goodbye,b
Goodbye,c

Checkout the go playground here

Firing the blur event when a component unmounts

If an input is focused and a React component containing that input unmounts, then the blur event for that input will not fire. If you use the blur event to save the contents of the input then you are in trouble.

You can know what input/select on the page currently has the focus with document.activeElement. Combine that with the component lifecycle method componentWillUnmount() to fire blur for the currently focused element on unmount.

componentWillUnmount() {
  const input = document.activeElement()
  input.blur()
}

The documentation for activeElement says it may return <body> or null when there is no active element, so you need to protect against that.

componentWillUnmount() {
  const input = document.activeElement()
  if (input) {
    input.blur()
  }
}

Mix xref and Elixir compiler warnings

The release of Elixir v1.3 added a mix task called xref for performing cross reference checks of your code. mix xref gives us some handy tools!

Find unreachable code:

❯ mix xref unreachable
lib/exonk8s/foo.ex:16: SomeModule.non_existant/0

Find callers of modules and functions:

❯ mix xref callers SomeModule
lib/exonk8s/foo.ex:16: SomeModule.non_existant/0

Generate a dependency graph:

> mix xref graph
lib/exonk8s.ex
├── lib/exonk8s/repo.ex
└── lib/router.ex
    └── lib/exonk8s/musician_controller.ex (compile)
        ├── lib/exonk8s/foo.ex
        ├── lib/exonk8s/musician.ex
        └── lib/exonk8s/repo.ex
...snipped for brevity

The release of Elixir v1.6 added the module attribute @deprecated to enable library authors to warn users of deprecated functions.

❯ mix xref deprecated
Compiling 2 files (.ex)
Foo Loaded
warning: ExOnK8s.Foo.lazy/0 is deprecated. You should be more eager.
  lib/exonk8s/musician_controller.ex:10

lib/exonk8s/musician_controller.ex:10: ExOnK8s.Foo.lazy/0

Lastly I should note that xref deprecated and xref unreachable are included in the compiler warnings, so you you’ve likely seen these at work even if you didn’t know they were there.

Learn more

Adding Decorators (And Store) To Storybook

We’ve been using Storybook to build and refine React components.

As we blur the boundary between the tool and our application (for example, importing an application component into a Storybook component) the workflow becomes complicated by dependencies like Redux. Storybook suddenly needs to know about the store.

There are multiple ways to handle this; the first is importing store at the top of you Storybook component hierarchy, then passing it as a prop all the way to the Redux-aware component.

A second is Storybook’s addDecorator function. With it, we can wrap the added component in Provider with store, allowing connect() calls to Redux:

storiesOf(‘My Components’, module)
  .addDecorator(getStory => <Provider store={store}>{getStory()}</Provider>)
  .add(‘Redux Aware Component’, () => <ReduxAwareComponent />);

Now we have a Redux-connected component in Storybook.

Multiple SSH Port Forwardings

This post by Dillon Hafer is one of my favorite remote-work tricks. Today I learned more about this part of the SSH configuration.

Multiple forwardings can be set; in a setup where port 3000 and port 9000 are important, we can forward both:

# ~/.ssh/config

Host example
  Hostname     example.com
  LocalForward 3000 localhost:3000
  LocalForward 9000 localhost:9000

Ports 3000 and 9000 will then be forwarded from the remote host. For a one-time solution, we can also add more via the command line:

$ ssh example -L 4000:localhost:4000

Combining this command and the configuration file above, ports 3000, 9000, and 4000 will be forwarded.

Enforce Specific Values With PropTypes

Being able to constrain our user interfaces to very specific values is valuable. This makes our interfaces easier to reason about and easier to test. PropTypes in general are one of the ways that we constrain our UIs. We can go even further than simple type constraints by limiting a prop to a specific set of values, an enum if you will.

MyComponent.propTypes = {
  flavor: PropTypes.oneOf(['Vanilla', 'Chocolate', 'Strawberry']),
};

The docs say about oneOf():

You can ensure that your prop is limited to specific values by treating it as an enum.

If we use MyComponent with a value such as Pistachio, we’ll have a console warning to answer for.

source

Get the response json with `fetch` and `Promises`

The fetch api is intertwined with the Promise api. The fetch function itself returns a Promise. The success function for that promise will have an argument that is a Response object.

fetch('myResource.json').then(function(response) {
  console.log('This is a response object', response);
})

The Response object implements Body which has several properties and several methods that help you to access the contents of the body of the response.

Body.json() is a function that reads the response stream to completion and parses the response as json. This operation may take take time, so instead of just returning the json, it returns another Promise. The success function of this promise will have the resulting json as an argument.

fetch('myResource.json').then(function(response) {
  response.json().then(function(parsedJson) {
    console.log('This is the parsed json', parsedJson);
  })
})

Of course, if you return a promise from a success function, then that promise will be resolved in the next chained then function.

fetch('myResource.json').then(function(response) {
  return response.json();
}).then(function(parsedJson) {
  console.log('This is the parsed json', parsedJson);
})

Create Listing Of All Middleman Pages

Middleman is a handy tool for quickly throwing together a bunch of static pages with layout and templating help at the ready. Once you have a handful of pages up and running, you’ll probably want a way to quickly navigate to them. You can add a quick listing of all the pages with a couple helpers provided by Middleman.

<ul>
  <% sitemap.resources.each do |resource| %>
    <li><%= link_to(resource.path, resource.path) %></li>
  <% end %>
</ul>

The sitemap.resources variable will contain a list of all the resources that get processed and served by the Middleman app. The link_to helper makes it easy to turn those into links.

Because resources includes images and other assets, you may want to filter down to just html files which could look something like the following:

<ul>
  <% sitemap.resources
       .select { |resource| resource.path =~ /html$/ }
       .each do |resource|
  %>
    <li><%= link_to(resource.path, resource.path) %></li>
  <% end %>
</ul>

Just add the snippet to whatever page you’d like the page listing to appear on.

Pin item to bottom of container

In laying out the items of a container, I want an item to be pinned to the bottom no matter the size of the other content. I can do that with a mix of flex and margin: auto.

.container {
  display: flex;
  flex-flow: column;
}

.footer {
  margin-top: auto;
}

I had previously thought that flex box was more contained and wouldn’t change the behaviour of properties like margin: auto but it does!

Check out my codepen here.

H/T Vidal Ekechuckwu

Add React With Webpacker To A New Rails App

Webpacker makes it easy to manage app-like JavaScript in the context of a Rails app. React is a great candidate for this kind of webpack-powered JavaScript processing pipeline.

To set up a new Rails project with Webpack and React wired up, add the --webpack=react flag:

$ rails new rails-react-app --webpack=react

As part of the generated app, you will get a app/javascript/packs directory with a hello_react.jsx file that has a really basic React component.

source

Share SCSS Variables with Javascript

When working with React and Sass, sometimes you want to be able to share variables defined in the stylesheets with your React javascript code. This is actually pretty simple with Webpack.

First make sure webpack is set up to import scss:

// webpack.config.js
module.exports = {
  ...
  module: {
    rules: [{
      test: /\.scss$/,
      use: [{
        loader: "style-loader" // creates style nodes from JS strings
      }, {
        loader: "css-loader" // translates CSS into CommonJS
      }, {
        loader: "sass-loader" // compiles Sass to CSS
      }]
    }]
  }
};

Then define your variables export file:

// variables.scss
$white-color: #fcf5ed;
$dark-color: #402f2b;
$light-color: #e6d5c3;
$medium-color: #977978;
$alert-color: #cb492a;
$light-black-color: #706e72;
$black-color: #414042;

// the :export directive is the magic sauce for webpack
:export {
  whitecolor: $white-color;
  darkcolor: $dark-color;
  lightcolor: $light-color;
  mediumcolor: $medium-color;
  alertcolor: $alert-color;
  lightblackcolor: $light-black-color;
  blackcolor: $black-color;
}

Now you’re ready to import your variables to use with your React components:

import variables from 'variables.scss';

const CSS = {
  backgroudColor: variables.blackcolor
}

export default ({}) => {
  return <div style={CSS}>Content</div>
}

Add Elixir files to your compiled list

While working on an Elixir package today, I wanted to add the test/support directory to my compiled files. I knew the Phoenix Framework did this so I went there to take a look and discovered elixirc_paths.

The Phoenix frameworks example looks like this:

  # mix.exs
  def project do
    [
      ...
      elixirc_paths: elixirc_paths(Mix.env),
      ...
    ]
  end
  defp elixirc_paths(:test), do: ["lib", "test/support"]
  defp elixirc_paths(_),     do: ["lib"]

Perfect! Now we can add additional directories to our compiled path that are environment specific.

Seeding And Generating Random Integers In ReasonML

It is easy enough to generate a series of random numbers using the Random module’s int function.

Random.int(10);

This will generate a random integer between 0 and 9.

You may notice that the randomness is the same each time you run your program. That is because you have fixed seed. To make sure you have a different seed each time your program runs, you can initialize the random number generator with something different at each run, such as the current time.

Random.init(int_of_float(Js.Date.now()));

See a live example here.

Git Checkout Lines of Code in Vim

Use case: you’ve made a bunch of changes to a file, and want to reset certain lines of the file back to the HEAD commit, while keeping other changes.

To solve this with git-fugitive, view the difference between your working copy and HEAD via :Gdiff . This will open two panes, HEAD (left) and your working copy (right).

Find the lines you want to reset in the working copy. Highlight those lines in Visual mode, and enter :diffget. Your working copy will restore the difference, for just the highlighted lines.

Mutations with the graphql-client Ruby gem

The graphql-client is a really good library to consume Graphql APIs in Ruby.

You can execute a mutation the same way as if it was a regular query passing the variables you want to use:

require 'graphql/client'
require 'graphql/client/http'

module Api
  HTTP = GraphQL::Client::HTTP.new(ENV['GRAPHQL_API_URL'])
  Schema = GraphQL::Client.load_schema(HTTP)
  Client = GraphQL::Client.new(schema: Schema, execute: HTTP)
end

CreateCityMutation = Api::Client.parse(<<~'GRAPHQL')   
  mutation($name: String) {
    createCity(name: $name) {
      id
    }
  }
GRAPHQL

variables = {name: 'Jacksonville'}
result = Api::Client.query(CreateCityMutation, variables: variables)
puts result.data.create_city.id

Scoping Variables With A Block Statement

A solid way to keep code readable and easy to understand is to ditch the terse one-liners in favor of breaking things up across multiple lines and using self-documenting variable names. This isn’t all good though. Each new variable that is defined is a handle on some data that can be misused later in the syntax scope.

JavaScript has a nice way of being clear about the scope of certain variables:

let parsedDate;
{
  let [month, day, year] = input.split('-');
  parsedDate = new Date(year, month, day);
}

// do something with parsedDate

The month, day, and year variables are scoped to the { ... } which is a block statement. This helps communicate and enforce that those variables are only to be used in that very specific context. Other developers and our future selves won’t be able to erroneously use those variables.

Of course, breaking out a function is another way of accomplishing this. Sequestering code in a different part of the file is not always the best answer though. Sometimes you want it locally fenced off. For those times, use a block statement.

Apply Styles To the Last Child Of A Specific Type

The :last-child pseudo-class is a way of specifying styling that will only be applied to an element if it is the last child among its siblings. What if we have elements that are declared amongst elements of another type? This can complicate that styling.

The styling

span:last-child {
  color: red;
}

won’t take effect on our last span here

<div>
  <span>One</span>
  <span>Two</span>
  <span>Three</span>
  <div>Something unrelated</div>
</div>

because amongst its siblings it isn’t the last.

One way of getting around this is with the :last-of-type pseudo-class.

span:last-of-type {
  color: red;
}

See a live example here.

Show The Good And The Bad With Git Bisect

The git bisect command is a powerful tool for tracking down a past commit where something verifiable about the code changed — whether it be visual or functional. After using git bisect to traverse back and forth through your commit history, you may be wondering where things stand.

The git bisect log command will show you each commit that has been inspected and whether you’ve marked it as good or bad.

These records can be handy for double checking your work if you’re worried that you made a mistake along the way.

String Interpolation With Quoted Strings

Stapling strings together with the ++ operator can be tedious and clunky. If you have string variables that you’d like to interpolate, you can piece them together much more easily using quoted strings.

We can get close to a solution with the standard quoted string syntax.

let greeting = (greetee) => {
  {|Hello, $(greetee)!|}
};

Js.log(greeting("World")); // => "Hello, $(greetee)!"

This isn’t quite right though. We have to take advantage of a preprocessing hook provided by Bucklescript. The j hook supports unicode and allows variable interpolation.

let greeting = (greetee) => {
  {j|Hello, $(greetee)!|j}
};

Js.log(greeting("World")); // => "Hello, World!"

To use this pre-processor we have to include j in the quoted string like so {j|...|j}.

See a live example here.

Relative Dates with GNU date

GNU date ships with the ability to add and subtract dates. Using the -d flag one can add add or subtract years, months, days, weeks, and seconds. As an example here’s a future date helper:

in() {
  if [ "$(uname)" == "Darwin" ]; then
    gdate -d"$(gdate) +$1 $2" "+%Y-%m-%d"
  else
    date -d"$(date) +$1 $2" "+%Y-%m-%d"
  fi
}
~❯ in 7 days
2018-03-24
~❯ in 2 months
2018-05-17

This can be handy for some CLI utilities like Todo.txt.

For example:

~❯ t add Post first TIL due:$(in 3 days)
10 Post first TIL due:2018-03-20
TODO: 10 added.

Note: If you’re on a Mac you’ll need to install the GNU coreutils. By default all commands will be prepended with g, hence gdate above.

brew install coreutils

Check the man pages for more info.

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.

Specify different bundler groups with RAILS_GROUPS

Is there a gem that you want to include sometimes and not others? For instance, do you have multiple versions of staging with slightly different gemsets? You can manage that with custom groups.

group :apple do
  gem 'some_gem'
end

group :orange do
  gem 'some_other_gem'
end
RAILS_GROUPS=apple,orange rails console
> Rails.groups
[:default, "development", "apple", "orange"]

In the config/application.rb file, Rails.groups is passed to Bundler.require.

Bundler.require(*Rails.groups)

A React Component Is Just A Bag Of Data

If you write enough React using JSX, it is easy to forget that you’re not working with markup. Everything — divs, h1s, 3rd party components, your components — all get boiled down to JavaScript objects full of data.

Any given React component is really just a bag of data. Try doing a console.log to see. Here is an example from an earlier post.

const ParentWithClick = ({ children }) => {
  return (
    <React.Fragment>
      {React.Children.map(children || null, (child, i) => {
        console.log(child);
        return <child.type {...child.props} key={i} onClick={handleClick} />;
      })}
    </React.Fragment>
  );
};

const App = () => (
  <div>
    <ParentWithClick>
      <span>Click this span</span>
    </ParentWithClick>
  </div>
);

Looking in the console, we see the following output:

Object {type: "span", key: null, ref: null, props: Object, _owner: Object…}
 type: "span"
 key: null
 ref: null
 props: Object
  children: "Click this span"
 _owner: Object
 _store: Object

It contains information about the component itself and because of the tree structure of this data, you could potentially expand the props —> children sections several times for certain components.

See a live example here.

Change Name of :id Param in Rails Resource Routing

You can change the name of the parameter used by rails resource routing by specifying the param option to the resource route.

For example, if we have a show endpoint:

resources :pages, only: :show

Running rake routes will return the pages#show url as:

/pages/:id

We can change the id param to slug by doing:

resources :pages, only: :show, param: :slug

Then running rake routes will yield our new pages#show route as:

/pages/:slug

Shell into a stopped docker container

If you are experiencing an error trying to run your docker container then maybe you need to do some debugging inside of the docker container. But how do you shell into a container if you can’t even start it?

docker run -it --rm --name newname myimage:latest bash

This takes your image and starts a new container, running bash and allowing you to examine your container.

-it allows you to attach a terminal.

--rm will clean this container up when you are done with it.

--name <something> is the name you give your new container.

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.

Remove indentation from heredocs

Ruby heredocs are a convenient way to include a block of text in Ruby source. Unfortunately, if the text is indented properly with the rest of the code the actual string is also indented. This is often undesired. However, it can be fixed by using the squiggly heredoc.

lorem = <<~STR
  Lorem ipsum dolor sit amet,
  consectetur adipiscing elit,
  sed do eiusmod
STR

lorem #=> => "Lorem ipsum dolor sit amet,\nconsectetur adipiscing elit,\nsed do eiusmod\n"

The squiggly heredoc automatically removes any indentation that is applied to all lines.

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

Your slowest Elixir tests

Sometimes its handy to see what tests are taking the longest in an Elixir project.

Enter mix test --slowest N

Just replace N with how many slow tests you would like to see and you’ll get some handy output:

$ mix test --slowest 5

Top 5 slowest (17.6s), 30.2% of total time:
  * test enters a body that is too long (4504.4ms) (DeveloperCreatesPostTest)
  * test the page does not have a Create Post link (4384.9ms) (VisitorVisitsHomepageTest)
  * test and clicks 'like' for that post (3944.2ms) (VisitorViewsPostTest)
  * test fills out form and updates post from post show (2558.6ms) (DeveloperEditsPostTest)
  * test fills out form and submits (2255.5ms) (DeveloperCreatesPostTest)

Mapping Over One Or Many Children In React

In Dynamically Add Props To A Child Component, I talked about how a child element can be reconstituted with additional props. The approach I showed will only work in the case of a single child being nested in that component. What if you want your component to account for one, many, or even children?

React comes with a built-in function for mapping that handles these cases.

const ParentWithClick = ({ children }) => {
  return (
    <React.Fragment>
      {React.Children.map(children || null, (child, i) => {
        return <child.type {...child.props} key={i} onClick={handleClick} />;
      })}
    </React.Fragment>
  );
};

The React.Children.map function allows mapping over one or many elements and if children is null or undefined, it will return null or undefined respectively.

See a live example here.

Using an array literal to specify length

Go forces you to specify the length of an array when creating or declaring an array. If you don’t declare the length then its not an array its a slice. The syntax for declaring the array looks like this:

// array of length 3
var numbers = [3]int{1, 2, 3}

When we use an array literal with the {} to declare the values of an array, the length declaration becomes redundant.

//slice
var numbers = []int{1, 2, 3}

The above example, however shows the declaration of a slice not an array. To let the literal define the length of an array we can place the ... operator inside the [] square brackets.

var numbers = [...]int{1, 2, 3}

Now, we can add a fourth element to the array without also having to change the specified length.

Clip images in html with `clip-path`

You may have some images that have some annoying artifacts around the border, or maybe you just want an image to be a funky shape for design purposes. If so, then clip-path is the css property for you.

Check out this diamond shaped image from the mdn docs:

clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);

There are 4 functions, circle, ellipse, polygon, and inset, amongst a number of interesting options, some of which work in your browser currently, some of which may not.

Creating a vector for your specific shape might sound rough, but firefox has a built-in clip-path tool that can help you set it correctly in the browser.

Dynamically Add Props To A Child Component

If your component has an element nested in it, then it will receive a children prop. There are a number of things you can do beyond simply including the children as part of the rendered output of the component. One thing you can do is put additional props on the child.

const ParentWithClick = ({ children }) => {
  return (
    <children.type
      {...children.props}
      onClick={() => alert("You clicked me!")}
    />
  );
};

This ParentWithClick component will reconstitute its child component with its given props and a new onClick prop.

Here is how it can be used:

const App = () => {
  return (
    <ParentWithClick>
      <span>Hello!</span>
    </ParentWithClick>
  );
};

Click on Hello! and you’ll see the alert.

Minor caveat: multiple children and a string child will need to be handled differently.

See a live example here.

Who Is Your Favorite Child?

When we put some content inside the open and close tags of one of our components, we get access to it as the children prop.

const Parent = ({children}) => {
  return (
    <React.Fragment>
      <p>These are my favorites:</p>
      {children}
    </React.Fragment>
  );
}

const App = () => (
  <div>
    <Parent>
      Greg and Marsha
    </Parent>
  </div>
);

What happens if we also provide an explicit children prop to Parent?

const App = () => (
  <div>
    <Parent children={"Jan and Peter"}>
      Greg and Marsha
    </Parent>
  </div>
);

Which will take precedence when we destructure children in the parent component?

In the example above, we’ll still see Greg and Marsha rendered. The content placed inside the tags will take precedence over the explicit children prop.

See a live example here.

Rearrange items with `grid-template-areas`

You can arrange items with the css-grid property grid-template-areas without changing the structure of your html.

Here I have basic strategy for a 2x2 grid with item one in the upper left corner and item four in the lower right.

.container {
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: 1fr;
  grid-tempate-areas: 
    "one two"
    "three four";
}

.one { grid-area: one }
.two { grid-area: two }
.three { grid-area: three }
.four { grid-area: four }

I can rearrange my items just by changing the grid-template-areas property:

.container {
  grid-template-areas:
    "four two"
    "three one";
}

Now, item four is in the upper left corner, and item one is in the lower right.

A complete example is up at CodePen