April 1st, 2017

This month I learned - March 2017

This month I started collecting learnings I have during the day. These include CSS, JavaScript and Bash. Maybe there is also something new for you in there. Enjoy – here are the learnings I had in March.

Conditional properties with object spread

Kris Urbas shared a really neat trick to deal with conditional object properties using the object spread operator (currently at proposal stage 3).

const shouldAddProp2 = false;
const obj = {
  prop1: 2,
  ...shouldAddProp2 && { conditionalProp2: 2 }
}

// it's like
// Object.assign( obj, ( shouldAddProp2 && { conditionalProp2 : 2 } ) );

console.log( obj );

Today this snippet is still hard to read for me, so I have to figure out if I should use this in the future, but it's a neat trick for sure. You can play around with it in the Babel repl.

A use case for CSS min-content and max-content

Recently I came across the CSS width property values min-content and max-content. I haven't heard of these before and couldn't imagine when these values would be useful. So I asked Twitter to get some answers. As usual Sven Wolfermann helped me out and sent me a CodePen which showed when I'd want to use these values.

min-content max-content use case

As you see in the CodePen example the subline is controlling the overall width of the headline. If you would have asked me a month ago I'd probably would have said that this is not possible in CSS.

See the Pen CSS Question by @vasilis – min/max-content by Sven Wolfermann (@maddesigns) on CodePen.

I never had to build a layout like this, but good to know that it's possible. ;)

Powerful history command shortcuts in bash

Ashley Williams tweeted that !! in commit messages will be replaced with the last executed command.

It turns out this is nothing git specific but rather command line specific and there are a lot more:

  • !! - last command
  • !1 - first entry in history
  • !-1 - last entry in history
  • !ssh - last command starting with ssh
  • !:1 - first argument of last command

For the case of git this works only when using -m though. ;) If you want to read more about this Digital Ocean published a nice article on this topic.

Completion values in JavaScript

Paul Irish tweeted a while back a code snippet that puzzled him (and me).

> "omg"; var x = 4;
// "omg"

> eval( `"omg"; var x = 4;` );
// "omg"

We both expected that the "return value" of this lines will be undefined. It turns out what we see after evaluating these lines in a JavaScript console are not return values but rather a statement completion values. If you want to dig deeper in this topic Matt Zeunert enlightened me with his article.

You can import Google Analytics Stats in caniuse.com

Heydon Pickering shared a tweet mentioning that you can import Google Analytics stats in caniuse.com! Woah! 🎉

Double-click the edges of a window in macOS to expand it

I came across this tweet by Jason Miller which shows a feature of macOS I didn't know about. You can expand any window by double clicking its edges.

console.dir() is short for console.log( util.inspect() )

Sometimes when debugging node scripts via console.log you'll run into the situation, that console.log won't show you the complete object you want to inspect.

console.log( { foo: { bar: { baz: { foo: 'Show me!' } } } } );
// { foo: { bar: { baz: [Object] } } }

The solution to this problem is to use util.inspect which also includes the option to color the output.

console.log( util.inspect( { foo: { bar: { baz: { foo: 'Show me!' } } } }, { depth: null, colors: true } );
// { foo: { bar: { baz: { foo: 'Show me!' } } } }

Frederic Hemberger just told me that console.dir uses util.inspect under the hood, which means we can make it even shorter! 🎉

console.dir( { foo: { bar: { baz: { foo: 'Show me!' } } } }, { depth: null, colors: true } );
// { foo: { bar: { baz: { foo: 'Show me!' } } } }

Useful background-repeat options other than repeat

Kudos to Chris Coyier who posted an article on background-repeat. I didn't know about the properties space and round. 🎉

See the Pen The Different background-repeats by Chris Coyier (@chriscoyier) on CodePen.

finally in a try/catch statements really goes over everything

Today I woke up checked Slack and saw a little trick question by my friend Tomasz in one of the JavaScript channels.

function f() {
  try {
    return 'A';
  } finally {
    return 'B';
  }
}

f(); // ?

I don't use the finally block in try/catch statements very often so I was not sure what the return value will be for this snippet. It turns out the finally block goes over everything according to MDN:

If the finally block returns a value, this value becomes the return value of the entire try-catch-finally production, regardless of any return statements in the try and catch blocks.

So let's have a look at a few examples:

function f() {
  try {
    return 'A';
  } finally {
    return 'B';
  }
}

f(); // 'B'

// ***********************************************

function g() {
  try {
    throw new Error( 'Foo' );
  } catch( e ) {
    return 'A';
  } finally {
    return 'B';
  }
}

g(); // 'B'

// ***********************************************

function h() {
  try {
    throw new Error( 'Foo' );
  } finally {
    return 'B';
  }
}

h(); // 'B' (without throwing an exception)

// ***********************************************

function i() {
  try {
    throw new Error( 'Foo' );
  } catch( e ) {
    throw new Error( 'Bar' );
    return 'A';
  } finally {
    return 'B';
  }
}

i(); // 'B' (without throwing an exception)

finally overwrites return statements and also "catches" exceptions. Good to know. ;)

Skipped holes in JavaScript Arrays

Today I came along a code example that used the delete operator to remove an element from an array. This is an operation that is rarely useful IMO because it creates holes in an array.

let foo = [ 1, 2, 3, 4 ];

delete foo[ 1 ];
delete foo[ 2 ];

console.log( foo );
// logs in Chrome '[1, 3: 4]'

console.log( foo.length );
// logs in Chrome '4'

console.log( foo.toString() );
// logs in Chrome '1,,,4'

I think everybody should avoid holes in arrays, but I kept reading about it out of curiosity and discovered that array methods like forEach skip holes in arrays. I didn't know that. This makes sense, but bugs caused by this can takes ages to be found.

let foo = [ 1, 2, 3, 4 ];
delete foo[ 1 ];

foo.forEach( ( value, index ) => console.log( index, value ) );
// 0 1
// 2 3
// 3 4

At the end I'll still avoid the usage of the delete operator for arrays to not create holes, but I think it's good to know about these things...

If you want to read more about this topic I highly recommend you to check out Axel Rauschmayers's section about holes in JavaScript arrays in "Speaking JavaScript".

Any comments?