Designing for colour. Computer screens lie.

I’m putting together a new website today and implemented the classic web developer test: I set a background color of red on a div to check my build system was refreshing.

It worked. But with an odd side effect.

The red I saw looked pink on one screen (my laptop screen, in fact) and different shades of red-ish on my other 2 screens.

I have a 3-display setup at home – my laptop screen with 2 connected monitors on either side. I also run an application called F.lux all the time which essentially sets a night light (reduces blue light and runs a softer colour). But even with that turned off I still had colour variations across all three screens.

Unfortunately I couldn’t take a good enough picture to show the contrast clearly, but hopefully the following 2 photos give some idea:


Regardless, the moral of this story is:

No matter how precisely you design the colour of software or websites to look, there is no guarantee users will see what you expect them to see.

Keep your designs simple, focus on contrast and hope for the best.

And remember, there’s always grey scale to fall back on.

Notesheet: Webpack

Status: Work in Progress. Updated: 7 February 2020

Points of Interest




Webpack error “The operation was rejected by your operating system.”

I just tried installing webpack via npm in a new project and received the following. Notice the error in below near the end:


PS D:\Workspaces\profile-jsnelders-com> npm install webpack webpack-cli --save-dev
npm ERR! path D:\Workspaces\profile-jsnelders-com\node_modules\brorand\package.json.1891953989
npm ERR! code EPERM
npm ERR! errno -4048
npm ERR! syscall rename
npm ERR! Error: EPERM: operation not permitted, rename 'D:\Workspaces\profile-jsnelders-com\node_modules\brorand\package.json.1891953989' -> 'D:\Workspaces\profile-jsnelders-com\node_modules\brorand\package.json'
npm ERR!  { Error: EPERM: operation not permitted, rename 'D:\Workspaces\profile-jsnelders-com\node_modules\brorand\package.json.1891953989' -> 'D:\Workspaces\profile-jsnelders-com\node_modules\brorand\package.json'
npm ERR!   cause:
npm ERR!    { Error: EPERM: operation not permitted, rename 'D:\Workspaces\profile-jsnelders-com\node_modules\brorand\package.json.1891953989' -> 'D:\Workspaces\profile-jsnelders-com\node_modules\brorand\package.json'
npm ERR!      errno: -4048,
npm ERR!      code: 'EPERM',
npm ERR!      syscall: 'rename',
npm ERR!      path: 'D:\\Workspaces\\profile-jsnelders-com\\node_modules\\brorand\\package.json.1891953989',
npm ERR!      dest: 'D:\\Workspaces\\profile-jsnelders-com\\node_modules\\brorand\\package.json' },
npm ERR!   stack: 'Error: EPERM: operation not permitted, rename \'D:\\Workspaces\\profile-jsnelders-com\\node_modules\\brorand\\package.json.1891953989\' -> \'D:\\Workspaces\\profile-jsnelders-com\\node_modules\\brorand\\package.json\'',
npm ERR!   errno: -4048,
npm ERR!   code: 'EPERM',
npm ERR!   syscall: 'rename',
npm ERR!   path: 'D:\\Workspaces\\profile-jsnelders-com\\node_modules\\brorand\\package.json.1891953989',
npm ERR!   dest: 'D:\\Workspaces\\profile-jsnelders-com\\node_modules\\brorand\\package.json',
npm ERR!   parent: 'profile-jsnelders-com' }
npm ERR!
npm ERR! The operation was rejected by your operating system.
npm ERR! It's possible that the file was already in use (by a text editor or antivirus),
npm ERR! or that you lack permissions to access it.
npm ERR!
npm ERR! If you believe this might be a permissions issue, please double-check the
npm ERR! permissions of the file and its containing directories, or try running
npm ERR! If you believe this might be a permissions issue, please double-check the
npm ERR! permissions of the file and its containing directories, or try running
npm ERR! the command again as root/Administrator (though this is not recommended).

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\jsnel\AppData\Roaming\npm-cache\_logs\2020-02-06T20_06_02_861Z-debug.log
PS D:\Workspaces\profile-jsnelders-com> npm install webpack webpack-cli --save-dev
+ webpack@4.41.5
+ webpack-cli@3.3.10
added 10 packages from 6 contributors, updated 1 package and audited 8965 packages in 9.19s
found 0 vulnerabilities

PS D:\Workspaces\profile-jsnelders-com>

npm ERR! the command again as root/Administrator (though this is not recommended).

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\jsnel\AppData\Roaming\npm-cache\_logs\2020-02-06T20_06_02_861Z-debug.log


I just re-ran the npm install ... again and it worked fine the second time. As the message suggests, it was probably a system process in Windows locking the file the first time.

CSS Stacked Paper Effect with Fade Out Transition

A little project I started late tonight.
I want to create a web page that looks like it has a stack of paper, where you can “flip away” the top page after you finish reading it. Similar to a “flip book” (see turn.js as an example) but having only a single page showing at a time (vs the 2-page “open book” every other solution goes with).


I found the CodePen which I forked as a starter for the version I’m now developing:


I still have a few features to add:

  • Page curl at the top right (possibly).
  • Responsive design for different screen sizes. I’m not sure what I’m going to do about that at the moment.
  • External forward and back controls.
  • List all pages (or pages already read) so you can quickly go back.
  • Give pages a title, and an optional number.

I’ll continue to work on this over the coming days and provide updates here.

Notesheet: Babel (JavaScript)

Status: Work in Progress. Updated: 7 February 2020


  • npm install --save-dev @babel/core @babel/cli @babel/preset-env. Install locally in your project and add it as a dev only dependency.
  • Add a .babelrc file to the root of your project. This is the Babel configuration file.
      presets: ['@babel/preset-env']
      "presets": [
            "targets": {
              "browsers": ["last 2 versions", "safari >= 7"]
  • Create a “source” directory (and sub-directories) when all source files live (e.g. “src”, “src/js”, “src/css”, etc). In my examples it’s src.
  • Create a “build” directory where all your compiled/transpiled and ready to use files are placed (e.g. “dist”, “build”, “public”). In my examples it’s dist.


Running with NPM

  • Create an NPM “script” to run it (will have to be run manually. Eg:
    "scripts": {
      "build": "babel src -d dist"
  • Run npm run build on the command-line and Babel will transpile all JavaScript under the “src” directory and produce output files in the “dist” directory.


Running with webpack

  • npm install webpack webpack-cli --save-dev – Install webpack and the CLI.
  • Add a “script” to npm’s packages.json:
    "scripts": {
      "build": "webpack --config webpack.config.js"
  • Create a webpack.config.js in the root of the project
    const path = require("path");
    module.exports = {
      mode: 'development',
      entry: "./src/js/index.js",   // Note: "src" is the source directory name from above.
      output: {
        path: path.resolve(__dirname, "dist"),   // Note: "dist" is the build directory name from above.
      filename: "bundle.js"
  • Run npm run build to build files into the “dist” folder.
  • Install the Babel loader for npm install babel-loader babel-core --save-dev.
  • Add the following to your webpack.config.js file:
    module.exports = {
      // ... existing content is here ...
      module: {
        rules: [
            test: /\.js$/,
            exclude: /(node_modules)/,
            use: {
              loader: "babel-loader",
              options: {
                presets: ["@babel/preset-env"]
  • “This uses a regex statement to identify the JavaScript files to be transpiled with the babel-loader, whilst excluding anything in the node_modules folder from that. Lastly, the babel-loader is told to use the babel-preset-env package installed earlier, to establish the transpile parameters set in the .babelrc file.” [src]
  • Run npm run build again.




Looking into:

Notesheet: JavaScript

Status: Work in Progress. Updated: 4 February 2020

Truthy & Falsy


Immediately-Invoked Function Expression (IIFE) (“iffy”)

  • Is an unnamed function (so no global scope pollution) that is executed as immediately after it is defined.
    • It can only be called once and not again later, because their is no name hanging on global scope to call.
  • All variables and functioned defined within an IFFE are in their own local/private scope.
  • It is also known as a Self-Executing Anonymous Function.
  • You can return a value from an IIFE and store the result in a variable.
  • You can also pass in arguments to the anonymous function.
  • What scenarios would you want to use an IIFE in real life (what’s an example)? I did work on a project once that used it, but can’t remember how it helped us.




  • The context of execution.
  • The context in which values and expression can be referenced.
  • Global scope: In front-end web development this is the highest level (generally page level) and any variable or function defined in global scope can be access by another other function.
  • Local scope: Think of it as the scope contained within a function. Variables and nested functions defined within a function cannot be accessed by external functions.
    • A nested function can access variables and functions defined in parent (and ancestor) scope, but parents cannot access variables and functions defined in children.


Lexical Scoping

  • Describes how a parser resolves variable names when functions are nested.
  • The word “lexical” refers to the fact that lexical scoping uses the location where a variable is declared within the source code to determine where that variable is available.
  • So, nested functions have access to variables declared in their outer scope.



  • Unlike other languages, in JavaScript you can define a variable (e.g. var myVariable;) in you code after you access it (set a value or read it).
  • In other languages trying to access a variable before you first define it will cause an “undefined variable” type error.
  • Hosting allows this later definition.
  • It “conceptually” moves (hoists) the definition of the variable to the top of the scope it is defined in, so it is already available when the lines that access it are executed.
  • JavaScript does not rearrange your code.
  • What happens is during code compilation the variables definitions (also function definitions) are found and loaded into memory at the top of their scope.
    • This scope can include Global Scope and Local Scope. Local scope may be the full scope of a function.
    • As of ES2015, variables defined with “let” can be hoisted to the top of their “block” level scope (the scope defined within a set of opening an closing curly braces (i.e. “{” and “}”). For example, within an if() or for() statement.
  • Then during the next phase – code execution – they are available.



  • In JavaScript a function can be defined within another function.
  • The inner function has access to variables in the scope of the outer function and other parent-of-parent (ancestor) functions.
  • Closure is the ability for the inner function to continue accessing the variables of the parent scope when it is being executed later.
    • i.e. the outer function returns the inner function (or an object containing the inner function) and that inner function is run some time later in code execution.
  • Each instance of the returned inner function has access to its own copy of the variables in parent scope.
  • It allows you create units of “closed” and re-usable functionality, with data (variables) that do no clutter global scope.







The Key to Success

The answer you usually hear in speeches is “follow your passion”.

Bulls**t! The person saying that is almost always already successful and rolling in money thanks to a stroke of good luck.

The real answer is much harder:

Find something you’re good at and spend a few decades working your ass off!

And while you’re doing that you’re going to fail multiple times.
You’re going to work for people you hate. In jobs that suck the life from you.
You’re probably going to get depression.
And a mid-life crisis. Not to mention being hit by a few other crisis’s along the way.

You’re going to want to give up (many times). Then find enthusiasm aging. And give up.
You’ll be told you’re an idiot. And lose friends. Question yourself daily. And maybe have the odd good moment, only to be followed by more crap.

It is going to be a hard, often lonely, slog.

I know this:

I’m living it.

I’m not successful. Not the success I’m have in mind. But I want to me. I will me. I’m working hard for it. And if I don’t get it I’ll die trying.

Until then I work every day for it. Not 80 hour weeks – not anymore. That is, not wasted 80 hour grinds.
I’m still “working” every minute I’m awake, but I’ve learnt to re-focus some of that energy to other things: Learning. Thinking. Walking. Rest. Re-evaluation.

True success isn’t the founders of Facebook, Google or Tesla. They got lucky. Yes, the did some work, but not what the work everyone else has to do.

For the average person success is a lot a vision and a lot of guts, the ability to adapt, and the fortune to positions themselves to strike when opportunity is right.

And a hell of a lot of hard work and failure leading up to it.

I’ll be an overnight success some day…. 20-something years in the making.

Notesheet: ES6/ES2015+ (JavaScript)

Status: Work in Progress. Updated: 3 February 2020

Arrow Functions

  • Shorthand format for writing traditional functions.
  • Denoted by what some people call a “fat arrow”: =>
  • Removes the “function” keyword and often the “return” keyword and function block curly braces (“{” and “}”)
  • Formats can include:
    • () => { return …..; }
    • {x} => (return x+1; }
    • (x, y, z) => { if (x == 1} { return y; } else { return z; } }
    • Class.someFunction(x => x + 1);
    • var myFunction = x => x + 1;
    • var myFunction = x => { return x + 1; };


Traditional JavaScript function:

function sumOfNumbers(number1, number2)
  return number1 + number2;


ES2015 arrow function equivalent:

var sumOfNumbers = (number1, number2) => { var sum = number1 + number2; return sum * 2; }



Traditional “class” using a function

function Person(firstName, lastName)
  this.FirstName = firstName;
  this.LastName = lastName;

  this.GetFullName = function()
    return this.FirstName + " " + this.LastName;
var person = new Person("Bob", "Smith");

ES2016 Class

class Person
  constructor(firstName, lastName) 
    // FirstName and LastName properties are automatically created.
    this.FirstName = firstName;
    this.LastName = lastName;
  *	Method to return the full name.
    return this.FirstName + " " + this.LastName;
var person = new Person("Jason", "Snelders");


You can also define a property on the class like pre-ES2015, as in the following example.
Define it in the constructor() and you don’t have to pass a constructor parameter in to do anything with it (just give it a default value).
Then you can use the special “set” and “get” function to access it later. Or access it directly.
In this example “_displayName” is the defined property in question.
NOTE: You can’t use the same name for a property as the “set”/”get” function, so a good convention is to prefix the property with an underscore (“_”).
It’s still publicly accessible but represents a logically private property.


class User {
  constructor(username, password, loggedIn = false)
    this.username = username;
    this.password = password;
    this.loggedIn = loggedIn;
    this._displayName = "";

  set displayName(name) { this._displayName = name; }
  get displayName() { return this._displayName; }
    console.log(`Username: ${this.username}`);
    console.log(`Password: ${this.password}`);
    console.log(`Logged In: ${this.loggedIn}`);
    console.log(`Display Name: ${this._displayName}`);

// Create an object from the Class
const jason = new User("jason", "test123");


jason.displayName = "Jason Snelders";


jason._displayName = "Directly set _dislayName";

jason._displayName = "The Jason";


console.log(`Read directly from jason.displayName = '${jason.displayName}'`);

See it in action (open the Console) at


Define Variables: ‘let’ and ‘const (vs ‘var’)

  • Traditionally we only had ‘var’ keyword to define a variable.
  • ‘let’ is like ‘var’ but the variable is constrained to block scope – i.e. within the curly braces (“{” and “}”) it is defined between. For example, if() and for() statements.
  • ‘const’ is a constant with a value that is set at the time it is defined and that cannot be changes later.
    • The exceptions are:
      • arrays: values/elements within the array can be added and remove (but the whole array cannot be re-assigned).
      • objects: values of individual properties can be update, but the whole object cannot be reassigned.


Simple var, let and const

var aVariable = "One";
const aConst = "Two"
let aLet = "Three"

console.log(aVariable);  // Display "One"
console.log(aConst);     // Display "Two"
console.log(aLet);       // Display "Three"
aConst = "Four";	 // No. You cannot change a constant. Will produce a "Assignment to constant variable" error.
aLet = "Five";
console.log(aLet); // Now displays "Five"


Scoping ‘let’

if (aVariable == "One")
  // A new variable 'aLet' is defined within only within the block scope of the if() statement.
  // It will not affect the value of 'aLet' defined above.
  let aLet = "New Let";
  console.log(aLet);	// Display "New Let".

// We cannot see the 'aLet' defined in the if() statement 
// so we display the value of 'aLet' defined in the out scope 
// (i.e. the original aLet).
console.log(aLet);	// Display "Three"


Arrays as constants

const array = [1, 2, 3];
console.log(arrayToString(array));  //Display 1,2,3
// We cannot do this - re-assign the array.
//array = [4,5,6];	
// But we can still add/remove individual items from the array.
console.log(arrayToString(array));   // Display 1,2,3,7


Objects as constants

const person = {
  name: "Jason",
  age: "Old"
console.log(;   // Display "Jason"
// We cannot re-assign the object (like the array).
//person = { name: "Bruce" }; = "Bruce";
// But we can update individual properties on the object.
console.log(;   // Display "Bruce"


Example: using ‘let’ in counters to preserve existing variables.

//-- Traditional variables
var i = "Cat";
console.log(i);   // Display "Cat"
for (var i = 0; i<=5; i++)
  // Do something
The original declaration of 'i' was re-purposed for the counter.
console.log(i);   // Display "5".

//-- ES2015 example with 'let'
let i = "Cat";
console.log(i);   // Display "Cat"
for (let i = 0; i<=5; i++)
  // Do something
  console.log(i);   // Will update and display increasing from "1" to "5" with each loop.
// The original definition of 'i' in the outer scope (outside the for() loop) is preserved.
console.log(i);   // Display "Cat".


Default Function Parameter Values

  • A default value can be specified on parameters in the definition (signature) of a function.
  • If the function is called and that parameter is missed, the default value will be used.
  • If a value is passed in to the parameter then the supplied value is used.
  • Parameters without default values must appear before the first default parameter.
    • e.g. This is wrong myFunction(param1, param2 = ‘some value’, param3) because param3 does not have a default value but it appears after a parameter that does have a default.
    • Why? Consider calling the function: myFunction(‘first value’, , ‘third value);. Having a blank parameter when calling a function is not not valid code.


Traditional function

function aboutMe(firstName, lastName, location)
  return "My name is " + firstName + " " + lastName + ". I come from " + location + ".";

// This will error because the 'location' parameter is not passed in.
var result = aboutMe("Jason", "Snelders");


ES2015 function with a default parameter value

function aboutMe(firstName, lastName, location = 'Woop Woop')
  return "My name is " + firstName + " " + lastName + ". I come from " + location + ".";

// The default value of "Woop Woop" will be used for 'location'.
var result1 = usingDefaultParameters("Jason", "Snelders");
console.log(result1);   // Display: My name is Jason Snelders. I come from Woop Woop.
// The provided value of "Melbourne" will be used for 'location'.
var result2 = usingDefaultParameters("Jason", "Snelders", "Melbourne");
console.log(result2); // Display: My name is Jason Snelders. I come from Melbourne.


Reset Operator in Function Parameters

Example function definition:

function myFunction(myName, ...roles) 

The 3 dots preceding ‘roles’ (…roles) is the rest operator.

So if we call the function:

myFunction("Jason", "Developer", "Architect", "Lead", "Consultant");

The console output of ‘roles’ from that function will be an array:

["Developer", "Architect", "Lead", "Consultant"]



Template Literals

  • A string surrounded by back ticks  (`).
  • The string can be split over multiple lines.
  • You can embed literal references to variables in the same scope that are replaced when the string is “rendered” (aka “variable/expression replacement” or “string interpolation”).
  • A good option for “+” operator based string concatenation.
  • Any expression in JavaScript can be used within the curly braces (“{…}”).
var name = "Jason";
var statement = `My name is ${name}`;

console.log(statement);   // Displays "My name is Jason"

var multilineStatement = `My name is ${name}
and I am a software developer`;

console.log(multilineStatement);   // Displays "My name is Jason
                                                and I am a software developer".

Alternative to concatenation:

Old style:

var createUrl = function(domain, path) { return "https://" + domain + "/" + path;  }

With string literals:

var createUrl = function(domain, path) { return `https://${domain}/${path}`;  }


Other expression examples

`2 + 2 = ${2 + 2}`
`It is ${new Date().getHours() < 12 ? 'AM' : 'PM' }`


Spread Operator (…)


const myArray = [1, 2, 3];
console.log(...myArray); // Displays "1 2 3" (the individual values of the array).

Example scenario:

function add = (a, b, c) => a + b + c;
const myArray = [1, 2, 3];
add(...myArray);  // Returns "7"

Using the spread operator splits myArray and assigned each of the value to the arguments of the add() function we are calling.

Another example – add arrays together:

const array1 = [1, 2, 3];
const array2 = [4, 5, 6];
const array3 = [...array1, ...array2, 10];

This will create an array that looks like [1,2,3,4,5,6,10].

Similar Example with objects:

const obj1 = { name: "Jason" };
const obj2 = { location: "Melbourne" };
const obj3 = { ...obj1, ...obj2, "Learning": true };

We end up with an obj3 that l looks like:

const obj3 = { name: “Jason”, location: “Melbourne”, “Learning”: true };

And we can change = “Bruce” and remains as “Jason”.

Tagged Templates

  • Function that take a mix of string and variables, then formats and returns them based on some rules you apply.


Modules (“import” and “export”)

  • Code that can be written in one file and used in another (outside of the global scope).
  • Keywords “import” and “export”.
  • The name of the module is (by default) taken from the name of the .js file.
  • Each function we want to make available to other files is included in an “export”.
  • To use exported functions in other files we use the “import” keyword and reference the file to import from.
  • By default all exported functionality is imported, or we specify just the functions we want.
  • You can export a single default function (“export defailt …”) from a module and when importing you can give it any name you want.
  • NOTE: As of early 2020 modules is not handled well natively in Node (and I presume browsers) so you will need to use bundlers to get it working.



Other features to create examples for:

  • 22:34 Extended Literals
  • 24:42 Extended Object Literals
  • 28:18 Destructuring Assignment
  • Promises
  • async/await




Learning Resources

The responsibility of a software developer is to “deliver stakeholder value”

The responsibility of a software developer is to “deliver stakeholder value”.


Stakeholders are people and business.

We are tasked with creating things that provide positive value to those who commission it (the business) and use it (the customer).

Our responsibility and priorities are the following 3 tenents of software development:

Security: Ensuring the software we develop does not harm the business or customer, either directly or indirectly.

Usability: The customer can effectively discover, learn and usability the software in the easiest, most satisfying way possible. It should bring calm and cause a smile.

Sustainability: Ensuring once the software has been created it can be easily and effectively maintained into a long and unforseeable future. That includes ensuring it is cost effective, upgradable, extensible, buildable and deployable.


Software development is not about playing with technology.

It has nothing to do with language features, tools or frameworks.

Learning and change are not the reason for doing the work.

Cool should only apply when we find a way to improve on one of the tenents or delight a stakeholder.

Methodology, patterns, practices and paradigms are irrelevant if they don’t fit the tenents.

Explaining “The Cloud”

The “Cloud” is just computers that someone else owns and manage.

They own the hardware, make sure all the infrastructure (hardware and operating software) is kept up-to-date, and other people “rent” those systems to run their specific software applications.

All jokes aside, this explanation from Kitty is one of the best I’ve heard so far.