Basic Setup of TypeScript with Jest

We will take a quick look at how to set up a project using TypeScript and Jest. By adding Jest to the project from the beginning this should encourage test driven development – or at least that developers have minimal effort

Init Project

npm init -y
npm i -D typescript ts-node
tsc --init

npm i -D jest ts-jest @types/jest
npx ts-jest config:init

mkdir src
mkdir dist

Configure Project

tsconfig.json

For TypeScript you need to adjust a couple of variables like:

  • outDir = “./dist”
  • rootDir = “./src”
  • (optional) target: “es2017” (if you are not supporting IE11)
  • (optional) module: “esnext”
{
  "compilerOptions": {
   
    "target": "es2017",                          
    "module": "esnext",
    // ...
    "outDir": "./dist",  
    "rootDir": "./src",
    // ...
  }
}    

package.json

the only thing that remains is to add a couple of scripts to make development easier.

  "main": "./dist/index.js",
  "scripts": {
    "start": "ts-node ./src/index.ts",
    "test": "jest --watch",
    "build": "tsc"
  },

Init Git

It is always the best practice to use version control for coding projects – even if you are the only developer. Running Jest in “–watch” mode requires that the code is stored in a git repository

.gitignore

You need to tell git to exclude the node_modules folder. (This is done as the dependencies can be restored by running npm install). Create a file called “.gitignore” and add following line:

/node_modules

First commit

Since you have excluded

git init
git add .
git commit -m "Initial Commit"

Start Development

Demo Files

Create the files:

  • ./src/index.ts
  • ./src/index.test.ts

index.ts

export const greeting = () => {
  return "Hello World!"
}

index.test.ts

import { greeting} from "./index";

it('greets you', () => {
  expect(greeting()).toBe("Hello World!");
})

Run Demo / Start Development

Now you can start development by running

npm test

This will start jest and run your tests as soon as you change your code.

Design Failure: Removing the Minimize Button Elementary OS 5.0 Luna

Recently ElementaryOS 5.0 Juno got released. I immediately upgraded. Looked at it for two seconds and decided to go with Ubuntu.

The ‘killer’ feature that was missing was a small one – the minimize button is still not enabled by default.

Why was the minimize button removed?

Digging into this topic I found a statement about removing the default button.


a plan had already been laid out for the new standard of elementary apps: They would open and close instantly and even better, they would save their state before closing. 

Elementary Blog – Shaking up Window Controls (http://blog.elementary.io/post/107662532976/the-road-to-luna)

Basically they decided that elementary apps should act as mobile apps. Thus combining the minimize function with the close button.

Elementary OS is a desktop OS and if it wants to be successful it allows you to use all programs and not only apps designed for elementary OS.

Is it a good design decision?

Removing the minimize button is a bold move. It radically changes how the user deals with window management.

The Pros

Instead of minimize you need to use tools like multiple desktops Users could start working more with multiple desktops.

The Cons

  1. The concept of a minimize has been around since even before 1988 – It has become one of the core components of Desktop OS and Window management. Every user will have to relearn their interaction.
  2. The communication of the user with the computer is awkward and creates misunderstandings. The apps will guess what you want to do: Did you want to listen to music and keep the program open in the background or did you want to stop listening for music? The user has only one button to express both of these commands.

Probably the button is actually not used that often anymore, since most things are done with a browser and that window is always open. – I do not know I do not have any data to back that claim.

However I know that that line of thinking lead to the removal of the start button in Windows 8 and that was definitely not a good idea.

Goodbye Elementary OS

While Elementary OS has a wonderful UI and they try to focus a lot more on usability. The missing of this button makes the OS unusable for me.

In Elementary OS 0.4 Freya – I enabled the button with the command:

gsettings set org.pantheon.desktop.gala.appearance button-layout 'close,minimize,maximize'

However that made the UI look a little weird and sometimes it just did not work. I just assumed that when a lot of people are googling for the problem and mentioning it – that eventually they will reconsider their choice. However currently it does not seem to be the case.

So back to Ubuntu – that UI also has flaws, but it got it right to have a minimize button.

What is good code?

This is one of the biggest questions in programming. Everybody has an subjective answer to the question, as everybody develops their own style of programming over time.

For me good code has to fulfill these 5 criteria:

  1. Correct
  2. Efficient
  3. Simple
  4. Readable
  5. Maintainable

Now lets take a closer look at every criteria and what it means for your programming project

Correct

Code should have one key feature: It should work. Not functioning code is useless code.

Code has a very specific task it should do and it only should do that task. It should not do anything in addition that you do not expect.

Correct code also implies that it was built to specification . If you have a specification, you also can ensure that your code is correct by writing tests that verify that the code is doing exactly that what was specified.

Simple

If you have the choice between a complex expression and a simple expression that solves the same problem. then use the simple expression.

The complex expression is always a big door for unintended bugs. Additionally it makes it much harder to explain what is going on with your code.

Efficient

Efficiency, strongly depends on the values / non-functional requirements of your project.

It means if you can avoid costly operations, duplicate operations or unneeded operations. then you should optimize your code to avoid these kind of structures.

If possible you also should optimize for performance, however for most algorithms you need to decide a trade-off if your code will use a lot of memory or a lot of CPU. Before optimizing you always have to define for what you are optimizing.

Readable

Code is written for humans. Another human should be able to read your code.

If you use complex structures it just makes it harder for someone else to figure out what is going on in your project.

The compiler does not care if the variable is called “f” or “isActive” in both cases the compiler produces the same bitcode. Naming things is very important.

And never forget in most cases you are going to be the one that will revisit the piece of code and you will not know anymore what “f” is, but will immediately understand what “isActive” means.

Maintainable

Code is never done. There are a lot of things that causes that code needs to be adjusted in the future:

  • Additional Requirements
  • New Features
  • Dependency Upgrades

Now you can say, screw the maintainer of the project, you are only concerned about today. – However in most cases the guy that needs to fix something is the guy that created the code in the first place. – So do yourself a favor and write maintainable code.

What does it mean to write maintainable code? Have documentation, encapsulate functionality in a way

Conclusion

In the end good code is whatever you want it to be. If you are working with embedded systems and you want to create the most efficient algorithm, you will probably have other values as when you are working on a Web-Project.

You can define whichever values you want. The important thing is that these values must be clearly communicated to your team. Ideally by you leading as an example the others can follow.

In the end the goal of good code is that your project should deliver on time, suffer from less bugs, new team members can be easily onboarded, the team writes better tests and overall better communication (the specifications have to be more precise) etc.

Sources:

ImageDesigned by Freepik

Getting started with MOBX 5 and TypeScript 3, React 16.6

When looking around for example applications that use Mobx 5.x combined with Mobx-react 5.xand TypeScript 3.x I did not find any useful example. Most of the examples in the awesome mobx list reference Mobx 3.x and are really outdated.

In my example I will use MOBX to display “Hello World!”. It should showcase a couple of core concepts you will be using in an mobx application.

tl:dr: Source Code for this example can be found here.

Inititalizing the project

First we need to create our project. I will use following scripts to intitialize the project.

Create-react-app with TypeScript

npx create-react-app mobx-example
cd mobx-example
npm install --save typescript @types/node @types/react @types/react-dom @types/jest

npx mv 'src/App.js' 'src/App.tsx' 
npx mv 'src/App.test.js' 'src/App.test.tsx' 
npx mv 'src/index.js' 'src/index.tsx'

npm start

Note: I am using the npm package ‘mv’ to rename the files, this ensures that the script will work cross-plattform.

We need to run start in order to let create-react-app initalize all typescript configuration files.

MOBX

npm install --save mobx mobx-react

In the tsconfig.json you need to ensure that experimental Decorators are enabled. Add following line to your tsconfig:

"experimentalDecorators": true

Getting Started with MOBX

In order to use a MOBX Store you need to create a couple of things:

  • A Mobx Store
  • Configure the provider
  • Use the store in a component

The Mobx Store

Store Directory

It is advisable to keep your stores organized in a single directory like ‘src/stores’.

mkdir src/stores

The Example Store

From the offical documentation to create a store it would be enough to create a class as follows:

mobxStore.ts:

import {observable, action, computed} from 'mobx';

class MobxStore {
    @observable name = "World";

    @computed 
    public get greeting():string {
        return `Hello ${this.name}`;
    }

    @action.bound
    public setName(name:string):void {
        this.name = name;
    }
}

export mobxStore = new MobxStore();

Note: Using @computed is just a demonstration how you could create a calculated value from the current state.

When using TypeScript this is not be enough, you need to create an interface and let our Store implement it to ensure type safety in the react component.

export interface IMobxStore {
    name: string;
    greeting: string;
    setName(name:string):void;
}

Additionally we will move the initialization to its own class.

Finally our mobxStore.ts looks like this:

import {observable, action, computed} from 'mobx';

export interface IMobxStore {
    name: string;
    greeting: string;
    setName(name:string):void;
}

export class MobxStore implements IMobxStore {
     @observable name = "World";

    @computed 
    public get greeting():string {
        return `Hello ${this.name}`;
    }

    @action.bound
    public setName(name:string):void {
        this.name = name;
    }
}

Note: The interface could also be moved into a type definition file.

Store initialization

We will now create a file src/stores/index.tsIn this file we will create an object ‘stores’ that will initialize all stores that we are using in our application.

index.ts:

import { MobxStore } from "./mobxStore";

export const stores = {
    mobxStore: new MobxStore()
}

Configuring the Provider

Since we are ensuring that all stores are inititalized in a single object the configuration of the Provider is very simple In the file src/index.tsx you need to import the store object and the Provider from mobx-react:

import {Provider} from 'mobx-react';
import { stores } from './stores';

Then you need to wrap the <Provider />around the <App />. By using the spread operator for stores you ensure that all stores are registered in the provider.

<Provider {...stores}>
    <App />
</Provider>

Using the Store

In order to use a store in a component you need to inject the store into the component and (most of the time) you will also want to observe the store for changes.

The store will be accessable via the properties. Thus we need to define an interface containing an optional variable ‘mobxStore’ of the type IMobxStore. It needs to be optional due to TypeScript not knowing that the Store is provided by the inject method. If it would be mandatory TypeScript would throw an missing props error when using <App />.

This in turn causes TypeScript to complain that const {greeting} = this.props.mobxStore; is not allowed, as this.props.mobxStore could be ‘undefined’. By adding the Non-null assertion operator ‘!’ you can signal the TypeScript compiler to ignore this warning.

App.tsx:

import React, { Component } from 'react';
import './App.css';
import { observer, inject } from 'mobx-react';
import { IMobxStore } from './stores/mobxStore';

interface AppProps {
  mobxStore?: IMobxStore
}

@inject('mobxStore')
@observer
class App extends Component<AppProps> {
  render() {
    const {greeting} = this.props.mobxStore!;
    
    return (
      <div className="App">
        <header className="App-header">
            {greeting}
          <button onClick={this.clickHandler}>Change Greeting</button>
        </header>
        
      </div>
    );
  }

  private clickHandler = () =>{
    const {setName} = this.props.mobxStore!;
    setName("Bob");
  }
}

export default App;

Conclusion

Now if you run the application you should now see a wonderful “Hello World!” greeting and by clicking on the button it changes to “Hello Bob!” using mobx and typescript.

I hope this makes it a little simpler to get started with React, Mobx and TypeScript.

If you are interested in the project files you can get them from GitHub https://github.com/borgfriend/typescript-react-mobx-example

Ubuntu 18.10: NVidia RTX Drivers

NVidias newly released RTX Graphics cards will not be automatically detected by Ubuntu. In order to get the cards running properly you need to install the NVidia drivers with the version 410 or newer.

In order to install the driver you must run following commands:

sudo add-apt-repository ppa:graphics-drivers
sudo apt update
sudo apt install nvidia-driver-410 
sudo reboot

Dev Environment to Learn TypeScript

TypeScript is basically JavaScript with types. When writing your code you must define the types of your variables and optionally the returns of the functions. If you have been working with Java or C++ these concepts will feel very familiar.

However there is a small problem, TypeScript is not JavaScript – thus you need to use a compiler to convert your code into JavaScript.

This guide will take a look at how to set up a simple developer environment in order to play around with TypeScript.

Tools needed:

  • NodeJS 11 (It does not matter if you are using the LTS Version or the current Version)
  • VSCode

New Project

In order to create your first project you have to create a directory and initialize it with npm. You can use the Command Line and enter following:

mkdir learn-typescript
cd learn-typescript
npm init -y
code . 

When VSCode is open you can open a Terminal using Ctrl-`

TypeScript

Initial Setup

npm install typescript

this will install the typescript compiler (tsc) to your project. You then could run commands like tsc index.ts and it will compile it to index.js. Which you could execute with node index.js.

However you cannot directly debug your code and it is annoying to run the compile before execution.

Add TS-Node

TS-Node is a tool that allows you to directly execute TypeScript code. It uses the existing tsconfig.jsonto process the code.

npm install ts-node

now you could run the code directly via a command like:

ts-node index.ts

Configure VSCode Debugging Tools

Ts-Node also allows you to use the VSCode debugging tools.

Press Ctrl-Shift-P and enter “Debug: Open launch.json” (this will create a launch.json) Select “Node.JS”

{
  // Use IntelliSense to learn about possible attributes.
  // Hover to view descriptions of existing attributes.
  // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "request": "launch",
      "name": "Launch current file w/ ts-node",
      "protocol": "inspector",
      "args": [
        "${relativeFile}"
      ],
      "cwd": "${workspaceRoot}",
      "runtimeArgs": [
        "-r",
        "ts-node/register"
      ],
      "internalConsoleOptions": "openOnSessionStart"
    }
  ]
}

Now when you press F5 you can run and debug your typescript code. This also allows you to set breakpoints in VSCode.

Your first “Hello World”

Now create a new file called index.ts and add following code:

async function greeter(name: string): Promise<void> {
  await console.log(`Hello ${name}`)
}

greeter("World");

This “Hello World” takes advantages of Modern ES2017 Features “async/await” as well as adding types for TypeScript.

When you press F5 in VSCode this should result in an error as Promises are not available in ES5. We can fix this by configuring the compiler.

Configuring the compiler

In order to configure the compiler you need to run the command:

tsc --init

this will create a tsconfig.json file. with this file you can configure the compiler. When creating it with the command it creates the file with the defaults and comments on what each compiler flag does.

One of the settings you should adjust is the “target” attribute. Currently it defaults to “es5” – this is because Internet Explorer 11 only supports ECMAScript 5.

We are targeting with our code NodeJS 10+, so we can change this value to “es2017”. As you can determine from this table

Running Hello World again

Now press F5 again the output should show you “Hello World”.

Conclusion

Now you are set to experiment some more with TypeScript.

One of the things you can experiment with is changing the target version of the compiler and running tsc index.ts and take a look at the resulting JavaScript code. You will see that compiling to es5 or es6 the compiler adds a lot of extra code to enable functioning code, however when compiling to es2017 it (almost) only strips away the types and leaves the code practically identical.

Attachments:

Compiling the code to ES5

To fix the code to compile to ES5 we first need core-js a library that provides polyfills for older versions of JavaScript.

npm install core-js @types/core-js

now we must add the line index.ts:

import 'core-js/es6/promise';

async function greeter(name: string): Promise<void> {
  await console.log(`Hello ${name}`)
}

greeter("World");

and in our tsconfig.json: we must add:

"lib": [
      "es2015",
      "dom"
    ],

Now your code should compile and run on IE11.

Visual Studio Code Extensions (September 2018)

Lets take a look at a couple of very useful Visual Studio Code Extensions.

General

Settings Sync

The tool allows you to synchronize your settings on multiple computers and/or operating systems. You need to have a github account and it will create a secret gist in order to sync your settings. Read More

Settings Sync

Code Runner

Basically it adds a small play button at the top of every file and lets you immediately execute it.

Code Runner

Git Lens

Git Lens dramatically enhances the GIT experience in VSCode. Inline display of code authorship, easy comparison with previous versions of the file and many more features.

Git Lens

Code Quality

TODO Highlighter

It highlights your comments that start with \\ TODO: or \\ FIXME:. Additionally it adds a command to list all Todos in your source code so you can identify and complete / fix the code.

If you use a different convention in your codebase you can configure the plugin to fit your use case.

TODO Highlighter

Spell Checker

Basically this complains when you start creating variable names that have no meaning. While ensuring that your documentation does not contain any spelling mistakes.

You can add words to a project dictionary And it is easily expandable to support additional languages.

Spell Checker

TSLint

It uses the local tslint.json and integrates the information into VSCode. You can enable ‘tslint.autoFixOnSave’ that automatically applies the defined rules (that can be autofixed).

TSLint

Theme

Cobalt2

A great dark theme with high contrast color choices. Personally I do not follow the official documentation on how to set up the theme. (Too many steps and it requires the font Operator Mono that costs 200USD )

Cobalt2 Theme Official

VS Code Great Icons

Well better Icons for VS Code

Great Icons

Image: Designed by Freepik

CodeWars: Weekly Newsletter

8kyu – positiveSum

The first question is to sum up all the positive integers in an array. Basically two things need to be done:

  • Filter out Values that should not be added to the sum
  • Sum up every item in the array

Basically you can write the solution like this:

export function positiveSum(arr: number[]): number {
  return arr
          .filter(val => val > 0)
          .reduce((total, current) => total + current, 0)
}

It is important to note that the initial value of 0 must be set, as if you pass in an empty array it would return NaN

7kyu – next Prime

Basically you need to check every number if it isPrime. Then you need to select an algorithm that can check if it is a prime number.

In this case I just took the code from the npm package is-number-prime. Which is a brute force way of figuring out if the number is prime or not. (There is probably something more mathematically elegant out there)

function isNumberPrime(n) {
  if (n === 2 || n === 3){
    return true;
  }
  
  if (n < 2 || n % 1 || n % 2 === 0 || n % 3 === 0) {
    return false;
  }
  let foo = Math.floor(Math.sqrt(n));
  for (let i = 5; i <= foo; i += 6) {
    if (n % i === 0 || n % (i + 2) == 0) {
      return false;
    }
  }
  return true;
}

function nextPrime(n){
  while (true){
    n++;
    if (isNumberPrime(n)){
      return n;
    }
  }
}

CodeWars: Weekly Newsletter 02

8kyu – Logic Drills: Traffic light

You need a function to handle each change from green, to yellow, to red, and then to green again.

Based on how the question is formulated it is suggested that you should always return the next item in an array. If it is the last item it should return the first item.

/**
 * 
 * @param {'green'| 'yellow'| 'red'} current 
 * @returns {string}
 */
function updateLight(current) {
  let lights = ['green', 'yellow', 'red'];
  let nextIndex = (lights.indexOf(current) + 1) % lights.length;
  return lights[nextIndex];
}

However as alternative you also could say: We always already know the next state, we do not need to calculate the next state. For traffic lights this system also probably will never change. Thus you can use an object to save the next states.

/**
 * 
 * @param {'green'| 'yellow'| 'red'} current 
 * @returns {string}
 */
function updateLight2(current) {
    return {
    'green': 'red',
    'yellow': 'green',
    'red': 'yellow'
  }[current];
}

7kyu – Sum of numerous arguments

The idea of this problem is mostly to make aware of that you can pass in an arbitrary amount of arguments into a js function.

In ES5 you would be using the arguments object and iterate over the array. in ES6 however we can use the cleaner spread-syntax:

/**
 * 
 * @param {number[]} args 
 * @returns {number}
 */
function findSum(...args){
  if (args.find(val => val < 0)){
    return -1;
  } else {
    return [...arguments].reduce((total, current) => total + current);
  }
}

Dealing with the new Java Release Schedule

Oracle has just announced that the End of Support for Java 8 is going to be January 2019. This, in turn, means that every business using Java will need to upgrade for security reasons to the latest version of Java. The new release strategy says that newer versions have a 6-month support and then a new major version of Java is going to be released. In Addition, they are changing the Version naming scheme from SemVer to <year>.<month>Basically allowing Oracle to introduce breaking changes to Java every 6 months. As a business you basically are given the choice:

1. Upgrade Java every 6 Months

If we would go with the first option it already gets strange. At the moment assuming you are currently on Java 8 you would need to directly update to Java 10, as Java 9 Support already has ended. However, you still would first need to update to Java 9 just to see what all does not work anymore due to Java 9 major changes and then move to Java 10. But that is assuming that your 3rd Party libraries also already did the update to the new version. Then in September, you would upgrade to Java 11. A lot of people are going to say, well good then we just do not upgrade now and wait for September to do the upgrade. Yes, you can do that, but that does not really matter as in the following March you anyway would have to upgrade again. Your business needs a new strategy how to deal with the rapid version changes. That is now only supported for 6 months instead of the ~3+ years. Personally, I really like this, as most businesses have the strategy: “Version upgrade? only when hell freezes over” – that only costs money and has no immediate benefits.  Focusing on the short-term impact, neglecting the fact that continuous upgrades are cheaper in the long-term and contain less risk compared to the big bang upgrades. Source: Java Release Roadmap

2. Get Java Advanced licenses (Extended Support)

The alternative is to just get the Java Advanced license. I could not find any information on the Oracle site. Basically, you are paying around 500usd/core (Source), so depending on how many servers you are using you will have to pay a small fortune. At the same time, you are only sidestepping the upgrade issue as you anyway have to upgrade your system every 3 years at least once.

3. Use another Language

Depending on your codebase you may want to look into moving away from Java. If you are starting a project you may want to look into C#, Python or JavaScript (or any other language) Many Java projects are anyway already running for 15+ years and may need a technological overhaul. You could think about switching to micro-services and start replacing a service one by one with another technology. While there are many costs and risks involved switching technologies, *developer training, system stability, continuous support etc. etc.

Conclusion

It really depends on your project and how your business deals with change how you ultimately deal with Release Schedule.  You definitely need a strategy how to approach this problem. The future of Java is unclear. Oracle is promising more rapid improvements of the language.  But there is the possibility that the changes are too drastic so that businesses will stop using the language. Either Java will continue to be one of the most used programming languages or fade into obscurity. The only thing that is certain is that the world of Java is going to be changing significantly in the next couple of years.