Monthly Archives: April 2015

Ember -> Heroku

After you’ve created a Ember-Cli app, create a Procfile, it will tell Heroku what to do when your application starts.

“Procfile is a mechanism for declaring what commands are run by your application’s dynos on the Heroku platform.”

touch Procfile

In Procfile.

web: ember serve --port $PORT --live-reload=false

In package.json make sure you have something like the following.

Note: the Ember team is depreciating Bower moving forward but Heroku is happy with it for the moment. This will install dependencies.

"scripts": {
    "start": "ember server",
    "build": "ember build",
    "test": "ember test",
    "postinstall": "./node_modules/bower/bin/bower install"
  },

Change the package.json node “devDependencies” to “dependencies” or change the Heroku config to use the Dev Dependencies with the following line.

heroku config:set NPM_CONFIG_PRODUCTION=false

If you are using external resources, in config/environment.js, do something like the following to get things running and then strip it back.

Note: use relative protocols to avoid mixed content issues.

“mixed content was loaded over HTTPS, but requested an insecure script”

Caution! This is for a TEST application that uses external javascript, fonts, images and stylesheets.

ENV.contentSecurityPolicy = {

    'default-src': "'self'",
    'script-src': "'self' http://localhost:4200 'unsafe-eval' * 'unsafe-inline' *",
    'font-src': "'self' 'unsafe-eval' * 'unsafe-inline' *",
    'connect-src': "'self'",
    'img-src': "'self' 'unsafe-eval' * 'unsafe-inline' *",
    'style-src': "'self' 'unsafe-eval' * 'unsafe-inline' *",
    'media-src': "'self'"
  }

EMBER INSTALL PROCESS

EMBER INSTALL PROCESS

# global install of ember / bower / watchman / phantomjs
npm install -g ember-cli
npm install -g bower
brew install watchman
which -a watchman
npm install -g phantomjs

# create project
ember new graceNote

# Switch to project folder
cd graceNote/
ember server 
# Cannot find module 'ember-cli/lib/broccoli/ember-app'
ls
npm install 
# Reload dependencies
ember server 
# More missing dependencies
bower install 
# Run `bower install` to install missing dependencies.
ember server 
# killed grunt server / Livereload failed on port 35729.  It is either in use or you do not have permission.
ember server 
# We're Up!

Open Chrome

Add the Ember Inspector

To include Node Modules to a project using Ember CLI, it looks like Ember-Browserify is the preferred way to add npm modules.

Ember Team – “we plan to drop bower_components entirely, likely no extra effort will be spent on this, rather that energy will go towards NPM improvements.”

npm install ember-browserify --save-dev

Observer Implementation – using defineProperties

Testing Object.defineProperties using the Observer pattern. MDN shows that defaults for configurable, enumerable and writable are false. The implementation below is explicitly setting those values to false as a reminder.

function MakeObservable(obj) {

    obj = obj || this;

    //obj._observers = [];

    Object.defineProperties (obj, {

        _observers: {
            value: [],
            configurable: false,
            enumerable: false,
            writable : false
        },

        _watch: {
            value: function (name, observer, func) {
                if (!obj._observers.hasOwnProperty(name)) {
                    obj._observers[name] = ({observer:observer, func:func});
                } else {
                    console.log('This property already exists on this object');
                }

            },
            configurable: false,
            writable : false
        },
        
        _unwatch: {
            value: function (observer) {
                var idx = obj._observers.indexOf(observer);
                if (idx > -1) {
                    obj.slice(idx, 1);
                }
            },
            configurable: false,
            writable : false
        },

        _updateWatcher: {
            value: function (observer) {
                console.log("Generic Notification from Watched Object\n - Cannot Customize");
            },
            configurable: false, 
            writable : false
        },
        
        _updateWatchers: {
            value: function (prop, value) {
                var len = obj._observers.length;
                for (var prop in obj._observers) {
                    // INTERNAL OBJECT NOTIFICATION
                    //obj._updateWatcher(obj._observers[watcher]);
                    // GET WATCHER
                    var watcher = obj._observers[prop];
                    // CALL WATCHERS CUSTOM METHOD
                    watcher.func(prop, value);
                };
            },
        },
        set: {
            value: function(prop, value) {
                obj[prop] = value;
                obj._updateWatchers(prop, value);
            }
        },
        get: {
            value: function(prop) {
                return obj[prop];
            }
        }
    });
    
    obj.set = function(prop, value) {
        obj[prop] = value;
        obj._updateWatchers(prop);

    };

    obj.get = function(prop) {
        return obj[prop];
    };

    return obj;
}

var obj = new MakeObservable();

// CREATE WATCHER
var watcher = {
    func: function(prop, value) {
        console.log("FIRST WATCHER", prop, value);
    }
};

// ADD WATCHER NAME, WATCHER AND FUNCTION TO BE CALLED ON UPDATE
obj._watch("watcher", watcher, watcher.func);

// TEST WATCHERS
obj.set('name', 'First Name');

// CREATE WATCHER
var watcher2 = { 
    func: function(prop, value) { 
        console.log("SECOND WATCHER", prop, value); 
    }
};

// ADD SECOND WATCHER NAME, WATCHER AND FUNCTION TO BE CALLED ON UPDATE
obj._watch("watcher2", watcher2, watcher2.func);

// TEST WATCHERS
obj.set('name', 'Second Name');

Javascript – Object.defineProperty – Eloquent Javascript – Chapter 6

This is the first time I’ve used Object.defineProperty. Below, I’m using it to create a property on an object. The requirement is that the property is a function that is called without parens.

It reveals some interesting things I’ve stumbled across recently. Console.log shows non enumerable properties when called on an object but those properties are not included in a for loop. Why? Because those properties have a property called enumerable that is set to false. If this property should show up in a for loop, include the following when using Object.defineProperty.

If you stumble across this blog, these are my programming notes more than a blog. If you have any comments or questions, feel free to comment.

        enumerable: true

Here’s an example of the code I wrote for the Vector assignment in Chapter 6.

function Vector(x, y) {

    // variables
    this.x = x;
    this.y = y;

    // functions
    this.powUp = function () {
        return Math.pow(this.x, 2) + Math.pow(this.y,2);
    }

    this.plus = function (obj) {
        return new Vector(this.x + obj.x, this.y + obj.y);
    };

    this.minus = function (x, y) {
        return new Vector(this.x - obj.x, this.y - obj.y);
    };

    // requires parens to call / reset value;
    //this.length = function() {
    //  return Math.sqrt(this.powUp())
    //}

    // removes the need for parens / adds code
    // extend the object 1st param
    // give it the name 'length'

    Object.defineProperty (this, 'length', {
        get: function () {
            return  Math.sqrt(this.powUp())
        }
        //set: function () {
        //  return  Math.sqrt(this.powUp())
        //}
    });

    // make it chainable
    return this;
};


// Object.defineProperty Notes:

    Object.defineProperty properties
    get: function() {}        // function to returns value
    set: function() {}        // function to set value
    value: 0,                 // current value
    enumerable: true,         // shows up in for loop
    configurable: true,       // prop can be changed / deleted
    writable: false           // can be modified

    // Can be expressed as an object
    /*
    Object.defineProperties (this, { 
        prop1: { get: function() {}, set: function() {} },
        prop2: { get: function() {}, set: function() {} }
    });
    */

Chrome Developer Tips and Tricks

We’ve all spent time solving problems that have been addressed in new releases of languages or tools. I just found the following and am surprised by the toolset available for troubleshooting in Chrome. If you find yourself troubleshooting Javascript, take a look at Tips and Tricks for Chrome Devtools before solving a problem that no longer exists. The following examples are taken from the Google Devtools page.

Grouping Console Log Items

Console will nest a series of responses that are preceded by console.group() and terminated by console.groupEnd();

Example:

console.group("Authentication phase");
console.log("Authenticating user '%s'", user);
// authentication code here...
if (!authenticated) {
    console.log("User '%s' not authenticated.", user)
}
console.groupEnd();

Table Formatting for Objects and Arrays

Console can output objects and arrays as a table with the headers the property names or array index.

console.table([{a:1, b:2, c:3}, {a:"foo", b:false, c:undefined}]);

Dir displays non-enumerable and hierarchical information. Exceptionally helpful for checking html elements.

console.dir(document.body.getElementsByTagName('a');

Track the Time it takes for a process to complete

console.time("Array initialize");
    var array= new Array(1000000);
    for (var i = array.length - 1; i >= 0; i--) {
        array[i] = new Object();
    };
console.timeEnd("Array initialize");

Image Aspect Ratio – CSS Object Fit / object-fit

Hell Yes!

Displaying images in a container div while respecting aspect ratio has always felt cumbersome. But, it looks like all of the past solutions are now giving way to object-fit. I’d seen this tag in the but the lack of cross browser support made it unusable prior to the addition of support by Firefox 36 and Safari 8 (and the announcement that IE is being discontinued).

A quick intro.

Note *object-fit requires that the img tag or containing element be given a width and height.

object-fit values.

fill : stretches the image to the requested height / width.

contain : retains aspect ratio using max width or height to calculate the ratio for the other side.

cover : fills the box using max width or height, allowing overflow.

scale-down : uses none or contain defaulting to which ever displays the image first.

none : if the original image fits, it is displayed

Example CSS:

img {
    width: 300px;
    height: 300px;
    object-fit: contain;
}

Example on CodePen

Again, object-fit is not supported by IE, but a polyfill is available and IE is on it’s way out.

Read MDN Object fit for more concise info.

And check caniuse.com for up to date browser support.