How to create static class constants in ES6

ES6 brings classes to JavaScript, but some things are not immediately obvious or entirely supported. For instance, there is no obvious way to create static class constants.

Here is the simplest way I have found to create constants:

class CurrentLocation {
  static get GEOLOCATION_ERROR() { return 'GEOLOCATION_ERROR'; }


  function isValid(){
    return this.status === CurrentLocationItem.GEOLOCATION_ACQUIRED

In the example below, you can use CurrentLocation.GEOLOCATION_ERROR anywhere, but myGeolocationItem.GEOLOCATION_ERROR will not exist, as static members are not visible to class instances. Moreover, children of the CurrentLocation class will not inherit these attributes.

How to speed up apt-get on Digital Ocean

For some reason, downloading packages using apt-get install was unusually slow on DigitalOcean this week, barely exceeding 4kbps. Since DigitalOcean droplets are configured to download packages from, all I had to do was to revert them to the default Ubuntu sources using these two commands:

sudo sed -i "s/mirrors.digitalocean/archive\.ubuntu/g" /etc/apt/sources.list
sudo apt-get update

Downloads are now as fast as they should be.

How to make sure your og:image is used by Facebook

You can define custom meta tags on your website to decide it will appear when shared on Facebook. One of them is the og:image tag.

Unfortunately, it does not work reliably, and even their Open Graph debugger won’t help you. For instance, I got the following message:

og:image should be larger: Provided og:image is not big enough. Please use an image that’s at least 200×200 and preferably 1500×1500. (Maximum image size is 5MB.) Image ‘url from image, size: 300x443px 97kb’ will be used instead.

My image fit all the criteria and even showed in the og:image preview, yet Facebook refused to use it. It turns out that EXIF data was the culprit. Stripping the image of EXIF data and reuploading it solved the problem. This odd solution is supported by members of various communities.

If you are using WordPress, you can use plugins to set Facebook meta tags and automatically strip images of EXIF data, but there is no plugin that lets you strip EXIF data only for featured images.

How to fix “Cannot read property ‘failedExpectations’ of undefined”

While running Karma unit tests, you might run into the following error: Uncaught TypeError: Cannot read property 'failedExpectations' of undefined. The cryptic error message might be a pain in the butt to debug, so let me save you some time.

In your tests, look for reassignment of the result variable. You are probably overwriting a variable from Karma, and this is what breaks your tests. In my case, I was assigning this.result in beforeEach, and renaming it to this.promiseResult fixed the error.

Deleting directories while preserving symlinks

At work, we needed to replace a pre-existing folder with a symlink. We wanted to symlink the user’s .git/hooks folder to ../build/git-hooks every time the script was run.

We wanted to delete .git/hooks if it existed and replace it with a symlink, but we also wanted to avoid deleting ../build/git-hooks‘s contents by accident if the symlink already existed.

Using rm .git/hooks was not possible. If .git/hooks was already a symlink, it would be deleted and we could simply recreate it. Perfect! However, if .git/hooks was a non-empty directory (it contains examples by default), it would not be deleted, and the symlink could not be created.

Using rm -r .git/hooks was also impossible. If .git/hooks was already symlinked, the -r flag would delete the contents of ../build/git-hooks.

This is how we solved the problem:

set -e  # Script exits with 1 on error


# Safely delete the folder or symlink
if [[ -L $git_hooks_dir ]];
    # Folder already symlinked. Recreate symlink in case the directory changed.
    rm -f $git_hooks_dir
    # Possibly an existing, non-empty folder. 
    rm -rf $git_hooks_dir

# Create the symlink
ln -sf $link_to $git_hooks_dir

How to throttle scroll events in AngularJS

If you watch the scroll event, you will probably find yourself handling far more events than you need. The scroll event fires really quickly, and that can be a problem on mobile devices.

The following Angular directive will call a specified scroll event every 250 milliseconds.

angular.module('hereApp.directive').directive('onScroll', function($timeout) {
    'use strict';

    return {
        scope: {
            onScroll: '&onScroll',
        link: function(scope, element) {
            var scrollDelay = 250,
                throttled = false,
                scrollHandler = function() {
                    if (!throttled) {
                        throttled = true;
                        scrollThrottleTimeout = $timeout(function(){
                            throttled = false;
                        }, scrollDelay);

            element.on("scroll", scrollHandler);

            scope.$on('$destroy', function() {
      'scroll', scrollHandler);

The scrollable element should look like this:

<div on-scroll="myScrollEvent()"></div>