Vue.js; AngularJS done right!

This post describes briefly my first impressions of working with the Vue frontend framework.

I have been using Vue for only a couple of days now and during these days I have created an example application (a bitcoin converter).

Before, I have created the same application using other frameworks like AngularJS and Backbone, so this makes a comparison between the use of different frameworks possible.

What is Vue?

According to Wikipedia:

Vue (pronounced /vjuː/, like view) is a progressive framework for building user interfaces.

Wikipedia

The core library is focused on the view layer only. Vue is perfectly capable of powering sophisticated Single-Page Applications.

Components

Vue allows to build large-scale applications composed of small, self-contained and often reusable components with their own view and data logic.

An application should consist of self-contained components

In Vue, a component is essentially a Vue instance with pre-defined options. Registering a component in Vue is straightforward:

// Define a new component called todo-item.
Vue.component('todo-item', {
template: '<li>This is a todo</li>'
})

Now you can compose it in another component’s template:

<ol>
<!-- Create an instance of the todo-item component -->
<todo-item></todo-item>
</ol>

Vue’s reactivity system

When a Vue instance is created, it adds all the properties found in its data object to Vue’s reactivity system. When the values of those properties change, the view will “react” by updating to match the new values.

I found it very similar to Angular’s scope and digest cycle with the exception that Vue does not have a separate digest cycle to handle the update of the DOM elements.

Template Syntax

Some of Vue’s syntax looks very similar to AngularJS (e.g. v-if vs ng-if). This is because there were a lot of things that AngularJS got right and these were an inspiration for Vue very early in its development.

Vue uses an HTML-based template syntax that allows you to declaratively bind the rendered DOM to the underlying Vue instance’s data. Vue can intelligently figure out the minimal number of components to re-render and apply the minimal amount of DOM manipulations when the app state changes.

<span>Message: {{ msg }}</span>

It supports the full power of JavaScript expressions inside all data bindings

{{ message.split('').reverse().join('') }}

Single File Components

A really nice concept so far only seen in Vue is the single file component.

These files have the .vue extension and contain all the code for a single component. HTML, JavaScript and CSS.

The single file concept is not yet incorporated in the demo application I mentioned in this blog post.

Documentation

Vue is without doubt the best documented frontend framework. The cookbook is really well written with lots of examples. It got me up to speed with Vue quick.

Example Application; Bitcoin Converter

The example application is a simple currency converter for Bitcoin.

Simple Bitcoin converter, written in Vue

An application that contains field validation, binding of data between model and template, live update of the exchange price calculation and a call to a remote REST endpoint.

Comparison with AngularJS

Actually, working with Vue feels similar to working with the early versions of AngularJS.

The only thing lacking in Vue is the two-way binding, but that actually is a good thing. To send the updated value back to the parent, you have to explicitly program it to send the modified value as an event back to the parent.

Conclusion

This is just my first attempt to build an application using Vue. For a future version, these are the topics I still have to take a look at:

  • State management with Vuex
  • Single file template .vue
  • TypeScript
  • Services
  • Transitions & Animations
  • Vue CLI

Resources

Convert USB Printer to Network Printer

If the API library only supports a network connection for printing and the printer is a device without network connector but with USB connector, then we have to be creative and create a configuration that handles the translation for us.

The machine I used for this purpose is a Linux server running Ubuntu 16.04 LTS. But this could also have been a Raspberry Pi for example.

The printer is an Epson TM-T88V. This is a Point of Sale POS / receipt printer.

HP JetDirect Protocol

A simple network protocol for print jobs that is still relevant today is JetDirect running on TCP port 9100. JetDirect was designed by HP in the early 1990’s. 

So what we actually want to accomplish is Linux to act as a network printer device on port 9100 that forwards all of the data to the USB connected printer. 

USB printer connected to server, server connected to network.

Determine the Printer’s USB Device

When the printer is connected to the USB port and switched on, a new USB device will appear under /dev/usb. The first USB device will most likely be assigned to /dev/usb/lp0. We can easily test the USB connection of the printer.

echo "Hi POS printer!" > /dev/usb/lp0

Configure xinetd 

The JetDirect protocol is just an ordinary network stream and actually not a real protocol. So all we need is a ‘network stream server’ like e.g. xinetd to listen on port 9100 and redirect this stream to the printer stream.

if xinetd is not installed yet, we first need to install it using apt-get:

# apt-get install xinetd

Now add port 9100 to the file /etc/services if not already added:

jetdirect 9100/tcp laserjet hplj

To start listening on port 9100, create the file /etc/xinetd.d/jetdirect with the following contents:

# Allow applications using the AppSocket / JetDirect protocol
service jetdirect
{
socket_type = stream
protocol = tcp
wait = no
user = lp
server = /usr/local/bin/jetdirect
server_args = 
groups = yes
disable = no
}

Now create the file /usr/local/bin/jetdirect, this bash script receives a stream from standard input and forwards it to device /dev/usb/lp0:

#!/bin/bash  
/bin/cat > /dev/usb/lp0

Restart xinetd to activate the new configuration:

# service xinetd restart

Test the Final Result

Everything should be up and running by now. To test the network printer connection execute the following command:

$ echo "Hi Network Printer!" | nc 127.0.0.1 9100 

Resources

Linux as a network printer device (Raw, port 9100) – https://unix.stackexchange.com/questions/203173/linux-as-a-network-printer-device-raw-port-9100

Using port 9100 to print to a Printer Queue on a Cups-enabled Server – https://www.freedomit.co.nz/kb-centos/76-using-port-9100-to-print-to-a-printer-queue-on-a-cups-enabled-server


Run Jenkins Automation Server as Docker Image

Introduction

Even for my side projects it is convenient to have my personal automation server run. As far as I know, this type of server is also known as Continues Integration CI environment and I use those terms interchangeable. Beside being convenient, it is also fun and I might even learn something from it!

The most popular open source CI at this moment is Jenkins. So that is the one I am going to install.

To simplify the installation of Jenkins I chose to use Docker. Why Docker? Because it can, it is popular and to learn something from it.

You might already know but just for the completeness. What is Jenkins and What is Docker?

About Jenkins

Jenkins is an open source automation server written in Java. Jenkins helps to automate the non-human part of the software development process, with continuous integration and facilitating technical aspects of continuous delivery. It is a server-based system that runs in servlet containers such as Apache Tomcat. 

Wikipedia

About Docker

Docker is used to run software packages called “containers”. Containers are isolated from each other and bundle their own application, tools, libraries and configuration files; they can communicate with each other through well-defined channels. All containers are run by a single operating system kernel and are thus more lightweight than virtual machines.

Wikipedia

Why Run Jenkins as Container?

Well, an advantage of running Jenkins as a container is that there is no need to install Java and other requirements to run Jenkins. It is easy to get the latest version of Jenkins, it is just a matter of starting docker. During start, Docker will test if it has the the latest version of the image available and will download the latest version if needed. Docker is already a requirement of Jenkins for running the pipeline in an isolated environment anyway, so that means no extra requirements beside Docker.

The Build Process

Getting up and running with Jenkins was indeed just a matter of starting the Jenkins image, so that was easy! I created my first multi pipeline project and started the build. The pipeline starts a new Docker environment and tries to start maven in it, but the first attempt running the Maven build process was not successful.

Unfortunately by default maven appears not to be installed within the Jenkins container. It needs to be added to the image. Beside maven, imagemagick is used in my JUnit tests, so let’s add that one also.

We are almost there, but starting a Docker container from Jenkins running from a Docker container is not possible by default. Jenkins will fail with the following error:

docker not found

The trick here is to install Docker on the Jenkins container itself and mount the docker socket into the Jenkins Docker container when starting Jenkins. Thanks to Tharaka Devinda for a solution to this.

Create Customized Jenkins Docker Image

To create a customized Jenkins Docker image with maven, imagemagick and the docker client added, create a Dockerfile with the following contents:

FROM jenkins/jenkins:lts
USER root
RUN apt-get update &amp;amp;&amp;amp; apt-get install -y maven imagemagick
RUN curl -sSL https://get.docker.com/ | sh

Start Customized Jenkins Docker Image

To make the configuration of the Jenkins server a little easier, I use docker-compose. Create a docker-compose.yml file with the following contents:

    jenkins:
    container_name: custom_jenkins
    build: ./
    ports:
            - "127.0.0.1:8080:8080"
            - "127.0.0.1:50000:50000"
    volumes:
            - /opt/jenkins_home:/var/jenkins_home
            - /var/run/docker.sock:/var/run/docker.sock
    environment:
            JENKINS_OPTS: "--prefix=/jenkins"
    restart: always

To start the server, just start “docker-compose”. Open the following URL in the browser: http://localhost:8080/jenkins 

Run Jenkins Behind Proxy

My development server contains multiple tools like Bitbucket and others. All of them run on different context paths and are secured with SSL. I use Apache to offload the SSL and to serve the pages.

The Apache reverse proxy configuration for this looks like:

ProxyPreserveHost On
ProxyPass /jenkins http://127.0.0.1:8080/jenkins nocanon
ProxyPassReverse /jenkins http://127.0.0.1:8080/jenkins
ProxyRequests Off
AllowEncodedSlashes NoDecode
RequestHeader set X-Forwarded-Proto "https"
RequestHeader set X-Forwarded-Port "443"

Since then my Jenkins build server is running fine.

Resources

Jenkins, the leading open source automation server:
https://jenkins.io

Stackoverflow: extend jenkins image to install maven:
https://stackoverflow.com/questions/46052711/extend-jenkins-image-to-install-maven

Blog: Running Jenkins on Docker — for a newbie:
https://medium.com/gdgsrilanka/running-jenkins-on-docker-for-a-newbie-855ad376500b

A fully functional Jenkins server, based on the weekly and LTS release within a Docker container:
https://github.com/jenkinsci/docker/blob/master/README.md

Running Jenkins behind Apache
https://wiki.jenkins.io/display/JENKINS/Running+Jenkins+behind+Apache

HTTPS is easy and completely free!

After watching a talk about encryption from Yan Zhu online (JSConf Budapest 2016 – Encrypt the Web For $0) I decided to try Let’s Encrypt again to enable HTTPS on a website. I used Let’s encrypt before in November 2015. At that time the Let’s Encrypt project was in private beta and required a lot of manual configuration to get things configured. But right now the tools to configure Let’s encrypt seem really really mature.

Let’s Encrypt!

To enable HTTPS on a website, you need to get a certificate file from a Certificate Authority (CA). Let’s Encrypt is a Certificate Authority.

My server runs Debian Jessie (version 8) and the webserver is Apache (version 2.4). I have access to the server through SSH. When shell access is available, Let’s Encrypt recommend to use the Certbot ACME client. It can automate certificate issuance and installation without downtime.

Configure webserver with Certbot

First add backports to the Debian /etc/apt/sources.list config.

deb http://ftp.debian.org/debian jessie-backports main

Install the Cerbot client.

# apt-get install python-certbot-apache -t jessie-backports

Start the interactive configuration process to enable HTTPS for the selected websites.

# certbot --apache

That’s it already! Now everything should be configured!

Optionally test your new Apache config with the following command

# apachectl configtest

The Certbot packages come with a cron job that will renew certificates automatically before they expire. Let’s Encrypt certificates last for 90 days. To test the certificate renewal

# certbot renew --dry-run

Test host certificate

The free online SSL Server Test from Qualys SSL Labs performs a deep analysis of the configuration of any SSL web server on the public Internet. Go test your new configured website.

https://www.ssllabs.com/ssltest/index.html

Resources

JavaScript Callback of Promise

Als je nu https://www.facebook.com opent, zie je dat de pagina meteen laadt. Je eigen foto linksboven is zichtbaar, de zoekbalk bovenaan het scherm en het menu aan de linkerkant. In de seconden daarna verschijnen langzaam de berichten op de tijdlijn, niet allemaal, maar alleen in het gedeelte van het scherm dat zichtbaar is. Als je nu naar beneden scrolt, zie je dat ook de oudere berichten pas op dat moment geladen worden.

Facebook laadt deze onderdelen na elkaar om er voor te zorgen dat de pagina snel zichtbaar is. Als Facebook zou wachten met het tonen van de pagina totdat alle gegevens en berichten geladen zijn, zou het zeker een aantal seconden duren voordat de Facebook pagina zichtbaar is. En volgens studies is het zo dat hoe langer het duurt dat een website laadt, hoe meer gebruikers afhaken.

Asynchroon programmeren

Met asynchroon programmeren voorkom je dat de code moet wachten op uitvoer voordat het verder kan. Bij Asynchroon programmeren vindt de communicatie binnen de code plaats met behulp van events en callbacks. Een callback wordt aangeroepen als de data beschikbaar is. Vanaf dat punt kan het programma weer verder.

Op het moment dat er asynchrone code aanwezig is, heeft de ontwikkelaar de keuze tussen het gebruik van Callbacks of Promises. Een Promise is een nieuwer concept. Het voegt een extra laag van abstractie toe aan de code.

In principe is er niets mis met een Callback, maar het wordt lastiger wanneer je te maken krijgt met geneste callbacks. Geneste callbacks ontstaan als er meerdere dingen achter elkaar uitgevoerd moeten worden en waarbij de nieuwe aanroep moet wachten op de vorige aanroep. In de code ontstaat dan de “Pyramid of Doom”. Dit maakt de code moeilijk leesbaar en om die reden kan je dit beter voorkomen.

pyramidOfDoom

Callbacks

Als voorbeeld het laden van een afbeelding. Het resultaat van het load proces vangen we af door callbacks te registreren:

var img1 = document.querySelector('.img-1');

img1.addEventListener('load', function() {
  // Image loaded.
});

img1.addEventListener('error', function() {
  // Image loading failed.
});

In het voorbeeld hierboven, kan het zo zijn dat ‘load’ event al afgevuurd is voordat de we begonnen met luisteren naar het ‘load’ event. In dat geval ontvangen we nooit de melding dat de afbeelding geladen is.

Dit probleem is op te lossen door extra code toe te voegen die kijkt naar de status van img.complete, maar dat maakt de code er niet duidelijker op. Om toch elegante code op te leveren, kunnen we gebruik maken van een Promise object.

Promise

In de praktijk

Een Promise is het object wat je terug krijgt uit een function call wanneer de waarde die de functie moet teruggeven niet direct beschikbaar is, maar je er niet op wilt wachten. Je krijgt dan een Promise object terug waar je een eventhandler aan kunt hangen welke uitgevoerd wordt als de functie klaar is.

Een Promise object kan slechts eenmaal van status wijzigen. Als de Promise de status “resolved” eenmaal heeft, kan deze status niet meer wijzigen.

Eenvoudig voorbeeld

Een voorbeeld van een Promise object in Angular. Een enkele call met success en error afhandeling.

DsrContact.query({relationId: controller.relationId}).$promise
    .then(function (contacts) {
        controller.contacts = contacts;
        
        // Etc.
    })
    .catch(function (response) {
        // Handle error.
    });

Chaining voorbeeld

Een voorbeeld van meerdere calls in serie uitgevoerd. Er is nog steeds maar één catch functie voor de error afhandeling.

DsrContact.query({relationId: controller.relationId}).$promise
    .then(function (contacts) {
        // Todo: Process contacts.
        return contacts;
    })
    .then(function (processedContacts) {
        controller.contacts = processedContacts;
        // Etc.
    })
    .catch(function (response) {
        // Handle error.
    });

Voorbeeld parallelle requesten

In dit laatste voorbeeld worden twee calls gelijktijdig uitgevoerd. Met de $q.all() functie wordt daarna gewacht totdat alle calls succesvol uitgevoerd zijn. Pas daarna wordt de $q.then() functie aangeroepen.

var sitePromise = DsrSite.query({relationId: controller.relationId}).$promise;
var assetPromise = DsrAsset.query({relationId: controller.relationId}).$promise;

// Execute REST calls in parallel.
$q
    .all([sitePromise, assetPromise])
    .then(function (values) {
        // All REST calls successfully.
        controller.sites = values[1];
        controller.assets = values[2];

        // Etc.
    })
    .catch(function (response) {
        // Handle error.
    });

Browser Support

Native Promises worden bij het schrijven van dit artikel inmiddels door alle browsers behalve Internet Explorer, ondersteund. Daarnaast bestaan er libraries als Q die Promises volgens de specificaties implementeren en ook te gebruiken zijn in oudere browsers.

Conclusie

Promises zijn een krachtige aanvulling die het schrijven van asynchrone code makkelijker en overzichtelijker maakt. Daarnaast zijn composities en error afhandeling eleganter te programmeren, de code blijft veel compacter, bevat minder indents en is daardoor veel beter leesbaar dan geneste callback functies.

Resources

Hack de ATAG One Android App

PlayStore-AtagOneApp
De ATAG One app, gemaakt door Applied Micro Electronics AME B.V.

De ATAG One app (voor iPhone en Android) benadert rechtstreeks via het locale netwerk de ATAG One thermostaat. Atag stelt helaas geen technische documentatie online beschikbaar hoe de thermostaat aan te sturen is. De enige manier om uit te vissen hoe de app “praat” met de thermostaat, is door de app te hacken 🙂

Lees verder…

ATAG One thermostaat

ATAG One thermostaat

Sinds een week of twee ben ik in het bezit van een ATAG One thermostaat in combinatie met een nieuwe ATAG E325EC ketel.

Bij de aanschaf heb ik getwijfeld tussen een Nest of deze thermostaat. De Nest ondersteunde een tijdje terug nog geen OpenTherm (sinds deze week de Nest v3 wel) waardoor de ketel niet modulerend aan te sturen is. De ATAG One werkt perfect samen met de ATAG ketel (daar ga ik vanuit). Daarom voor de ATAG One thermostaat gekozen.

Lees verder…

JSConf EU Berlijn – conferentiedag 1

De conferentie begint op zaterdag 13 september. Om 8:30 uur ontbijt. De koffie is vers en voor het ontbijt is er ruime keuze uit allerlei gezonde salades, veel vegetarisch.

De locatie van JSConf EU Berlijn is het Radialsystem V in Berlijn. Dit is een voormalig pompstation dat op dit moment fungeert als cultureel centrum.

Lees verder…