James D. Mosier

Implementing a service worker

April 19, 2016

The Background

Occasionally I am asked how I learn best. I always quickly answer, “by doing!”. That’s why I love sites like Egghead.io & Pluralsight, because I can follow along and create something tangible. So when I wanted to learn more about service workers recently, I decided to implement one on this website you’re reading now. It is the most basic of examples, because this site only serves static content, but regardless I found it beneficial in order to gain a better understanding of service workers and their uses.

Initially when hearing about service workers, in particular during Google I/O 2015, I wasn’t quite sure what their purpose was. After researching, I found a few main takeaways that were of interest to me:

  • They allow you to run multi-threaded JavaScript in the browser. Currently there is only 1 thread on any given browser that you can run code on, which inherently limits the speed & efficiency of your application.
  • They provide you with the ability to have offline application. They can store information locally in your browser for retrieval at a later time.
  • Think of it like a mini-application that gets installed when a user navigates to your website

In short, what I was hoping to do when implementing this was to allow a user to visit my site with a network connection and then visit it again at a later date with no network connection and receive the same experience. Unfortunately service workers only have limited browser support, so any real world scenarios (looking at your iPhone) are not possible (at the time of this writing).

The Implementation

I took inspiration from Jake Archibald as well as some articles published by Google (see below for some links) for my implementation. I simply cache my static assets and then capture any Google Analytics events to replay at a later date, when the user has a network connection again. Also service workers only work over HTTPS, but luckily Cloudflare provides this for free so that step was already solved.

Initially I was experiencing issues with my service worker not caching CDN assets, Google Analytics scripts to be exact. This was solved with a function that intercepts all requests to static assets and checks whether it is a Google Analytics resource or not. If it is, it stores the request in IndexedDB for later retrieval.

Other than that, the setup and execution of the service worker code was fairly straightforward. This is a very basic example, but service workers can be much more powerful especially for more dynamic sites. If you’d like to see what I did for this one, all of the code can be found on my Github.

Here are some other resources for learning more about service workers. Jake Archibald has a ton of articles as well as Google’s engineering team.


My learning continues. Loading a Google Map (see my contact page background for this) isn’t quite as easy as I was hoping. Currently I have disabled the service worker on my site until I resolve the issues with loading the Google Map from the service worker cache. So please don’t think of me as a liar, I promise I had a service worker working on here and it worked beautifully!!

Angular "ng-switch-when"

November 01, 2015

During the creation of a new feature, I came across an interesting built in AngularJS directive I had never seen before, ng-switch-when. Its functionality is pretty straightforward and the name really says it all.

The feature I was building called for a page where a user could make a decision between two options. Choosing one of those options would show 1 of 2 wizards to create some data for an admin. I didn’t want to create new routes for these wizards, so instead I used ng-switch-when to dynamically load the components when a user makes a selection.

The landing page, which contains the directives, went something like this…

<div class="wrapper" ng-switch="layout">
    <div class="make-a-selection" ng-switch-default>
        <div class="option1" ng-click="changeLayout('option1')">Go to option 1</div>
        <div class="option2"  ng-click="changeLayout('option2')">Go to option 2</div>

    <div ng-switch-when="option1" option1-component></div>
    <div ng-switch-when="option2" option2-component></div>

The markup above first defines an object, layout, which is the object in which to switch on. This is definied via ng-switch="layout". It also declares the default view to show, which is a div decorated with ng-switch-default. Within that div are the two options which have click handlers which hit a function in the pages controller (defined below). Lastly, the two components, which happen to be directives, have ng-switch-when attributes. Those attributes contain the object, which when “true”, will load the component.

The click handlers, ng-click="changeLayout('optionN')", are defined in the controller below. You pass in the component name to switch to, which then sets it on the layout object (which remember is defined on the wrapper element in the ng-switch). This is what triggers the change of what component is shown.

$scope.changeLayout = function (type) {
    $scope.layout = type;

Lastly the component directives below can contain really any logic you’d like. All of the “magic” that comes along with the ng-switch directive is shown above. Below is just for your reference…

    .directive('option1Component', option1Component);

function option1Component () {
    return {
        scope: {},
        templateUrl: '/Templates/Option1.html',
        controller: function ($scope) {
            // directive logic

Overall I found the ng-switch-when directive to be extremely useful to load in different components on demand, as opposed to loading all logic up front and just “showing” and “hiding” the components on click. As with any directive, you can pass data between the “parent” and “child” directives using the require attribute on the child directive.

AngularJS Filter Buttons for nested object properties

October 14, 2015

Filtering in Angular is really, really simple. The docs provide a good overview of how to filter a list on the fly via the filter attribute of ng-repeat. What the docs leave out (at least I haven’t found it anywhere) is how to filter a list on click of a button and to take it a step further: how to filter by a nested object property.

The implementation makes a lot of sense and at the end of the day, it works exactly how you think it should. I’ve created a JS Bin example of this. The code is also below, with explanations.

AngularJS Controller

The controller contains an array of objects (vm.products) and also a quick Lodash shortcut to grab all the specs objects, so we can loop through them in the UI to dynamically create the buttons. You can skip this step if you’d like and either hardcode the filter buttons or use a different method to extract the objects. Don’t include Lodash if you aren’t already using it.

var vm = this;

vm.products = [
    {name: 'T-Shirt 1', specs: {color: 'red'}},
    {name: 'T-Shirt 2', specs: {color: 'blue'}},
    {name: 'T-Shirt 3', specs: {color: 'green'}}

vm.specs = _.pluck(this.products, 'specs');

AngularJS Flavored Markup

The markup is where the magic happens. First up are the buttons to filter the list. We hardcode the “All” filter button, because that will never change. On ng-click it clears the vm.filterProducts object (so nothing is filtered) and also sets vm.filterToggle property to all which lets our ng-class know which button is active.

We then loop over the vm.specs object, which we set in our controller. In essence, this is just our list of colors. When a user clicks one of the buttons, vm.filterProducts is set by creating a nested object in the markup. Because the specs object contains the color property, we need to make sure the filter knows where the color property lives within the array. That is why we create the nested object.

You could just as easily hardcode all the buttons (and not loop over the vm.specs), but just in case our specs records change down the road, it’s better to be safe and extensible, than sorry.

<div class="filter-btns">
  <h4>Filter Products</h4>
  <button type="button" ng-class="{'active': vm.filterToggle == 'all'}" ng-click="vm.filterProducts = {}; vm.filterToggle = 'all'">
  <button type="button" ng-repeat="spec in vm.specs" ng-class="{'active': vm.filterToggle == spec.color}" ng-click="vm.filterProducts = {specs: {color: spec.color}}; vm.filterToggle = spec.color">

The second part of the markup contains the ng-repeat with the filter attribute pointing to vm.filterProducts, so when a button is clicked it sets the value to be filtered. Angular handles the rest by returning a new array that is automatically displayed in the UI.

  <li ng-repeat="product in vm.products | filter: vm.filterProducts">
    {{product.name}} in
    <span ng-style="{color: product.specs.color}">{{product.specs.color}}</span>

As I mentioned, looking back at the implementation, it makes complete sense we would need to create a nested object in the UI in order for Angular to know which property we are targeting in our filter. Check out the live example on JS Bin.

ASP.NET MVC AngularJS Routing & Setup

September 20, 2015

Setup of an AngularJS application, in particular routing, is typically painless and super easy to get started. There are so many great boilerplates. You may be wondering how this post will be different. If you spend any time in the .NET front end world and haven’t ever found yourself Googling, “asp.net mvc angularjs routing” consider yourself lucky. The big issue that I encountered when trying to setup a solution in Visual Studio using .NET MVC and Angular was that MVC has routing baked in, something that Angular also does really well. Naturally they are both competing for your affection. I found a bunch of great articles that helped me piece together a solution that worked best for my project.

Our Solution’s Needs

The main reason we chose to keep the ASP.NET MVC architecture around was to have a familiar server side language at our disposal. The application we were building is used to manage users and settings for the numerous scanning devices our clients use to scan in patrons at an event. Therefore, we needed authentication with AES-256 encryption and we didn’t want our key and vector strings hanging out in some JavaScript source file. So alas, we decided to use the server side features of ASP.NET MVC to take care of the initial login as well as changing passwords for users once they were authenticated.



A good first step in spinning up the solution is dealing with the ASP.NET MVC (MVC from here on out) features. Typically all of your MVC views would be .cshtml files and for good reason. Although with AngularJS, we don’t have a need for the great features you get by using a server side compiled file on the clientside. The two big points that come to mind are Razor’s data binding syntax and connecting views to MVC controllers. The only .cshtml file I kept around was Home/Index.cshtml file which I used as the layout for the application. You can delete all other folders and files in the Views folder. A brief version of this file looks like this:

<!DOCTYPE html>
<html ng-app="adminApp">
    <title ng-bind="title + ' | Admin App'"></title>
    <base href="/AdminApp/" />
<body ng-cloak ng-controller="RootController">
    <div ng-view></div>


Pretty standard stuff in the code above. The only thing to keep a mental note of is <base href="/AdminApp/" /> which our application will rely on for routing.

Note: Pay attention to ensure the _ViewStart.cshtml file doesn’t pop back up in the Views folder as we go along, when creating new controllers Visual Studio seems to regenerate this file.


One of the most important files and bits of code that might not be the prettiest is the RouteConfig.cs file which would typically handle our MVC routing without us making any changes to it. In this case, we create a new MapRoute called API which we can use to make $http requests in our AngularJS app to our MVC controller and return a JsonResult. The second MapRoute is an edited version of the default, with the major change being the URL which I changed to "{*url}" which will capture all requests (not prefixed with /api) and will hit our Home/Index controller action and kick off our application by returning the Home/Index.cshtml view which is our layout.

public class RouteConfig
    public static void RegisterRoutes(RouteCollection routes)

            name: "API",
            url: "api/{controller}/{action}",
            defaults: new { controller = "Login", action = "Authenticate" }

            name: "Default",
            url: "{*url}",
            defaults: new { controller = "Home", action = "Index" }

New “Views” folder

MVC treats the Views folder with special consideration; therefore I decided it was best to create a new folder called Templates. You can of course call this whatever you’d like, the only purpose it has is to house our HTML files. That’s right, no more .cshtml files - only HTML from here on out! Our only .cshtml file will be the Home/Index.cshtml file that was previously discussed.

AngularJS Pieces

Just as a note, the main structure of my JavaScript files looks like this:

└── app/
     ├── home/
     │     └── home.ctrl.js
     ├── root/
     │     └── root.ctrl.js
     ├── login/
     │     ├── login.ctrl.js
     │     └── login.svc.js
     ├── app.js
     ├── config.js
     └── config.route.js

Now that we have our server side routing in place, we now need to setup our Angular routing. We will follow a typical “stock” Angular methodology for this. You can use whatever router you please, such as ui-router or any other.


(function () {
    'use strict';

    var adminApp = angular.module('adminApp');

    // Collect the routes
    adminApp.constant('routes', getRoutes());

    // Configure the routes and route resolvers
    adminApp.config(['$routeProvider', 'routes', '$locationProvider', '$httpProvider', routeConfigurator]);
    function routeConfigurator($routeProvider, routes, $locationProvider, $httpProvider) {
        routes.forEach(function (r) {
            $routeProvider.when(r.url, r.config);

        $routeProvider.otherwise({ redirectTo: '/login' });

    // Define the routes
    function getRoutes() {
        return [
                url: '/login',
                config: {
                    templateUrl: 'Templates/Login/Index.html',
                    controller: 'LoginController',
                    controllerAs: 'vm',
                    title: 'Login'
            }, {
                url: '/',
                config: {
                    templateUrl: 'Templates/Home/Index.html',
                    controller: 'HomeController',
                    controllerAs: 'vm',
                    title: 'Home'


You’ve likely seen a version of this routing before when working with Angular, so I won’t waste time explaining it in detail. Just notice how all of our templates point to files in the /Template folder, because MVC let’s Angular handle all the routing.


That wraps it up! You’ll now have a fully functional AngularJS application, powered by ASP.NET MVC on the serverside! The only thing that MVC does for us, when it comes to routing, is point the server to the Index.cshtml page that then renders some markup and our Angular files. Then Angular will handle our routing from there on our.

Some quick Angular filters

September 15, 2015

While working on a medium sized AngularJS application, I’ve relied upon a few custom filters to fit my needs. They aren’t mind blowing, but nonetheless, still useful.

The first is a “sum the values” filter. It simply takes in an array and 1 (or 2) properties that are within that array to sum against all values in the add. It just adds all values with that property together and outputs the result. The logic looks like this:

angular.module('myApp').filter('sumValues', sumFilter);

function sumFilter() {
    return function (data, key1, key2) {
        if (typeof (data) === 'undefined' || typeof (key1) === 'undefined') {
            return 0;

        var sum = 0;

        for (var i = data.length - 1; i >= 0; i--) {
            sum += parseInt(data[i][key1]);

            if (typeof (key2) !== 'undefined') {
                sum += parseInt(data[i][key2]);

        return sum;

And the usage is simply…

<div>Total Hamburgers: {{burgersArray|sumValues:'Cheese':'Plain'}}</div>

The second filter that is really useful (that I can’t believe is not built in) is to convert a decimal number to a percentage.

The JavaScript uses the built in Angular $filter service to do its magic. We take in an input (decimal number) and returns an absolute value of a number multiplied by 100 and then tacks on a percent symbol to the end of the output.

        .filter('percentage', percentageFilter);

percentageFilter.$inject = ['$filter'];

function percentageFilter($filter) {
    return function (input) {
        return $filter('number')(Math.abs(input) * 100) + '%';
<div>{{device.BatteryLevel | percentage}}</div>

AngularJS Inline Edit Directive

September 12, 2015

I came across a great “inline edit” directive a while back for use with AngularJS. I found this originally on Plunker and made it my own. The general idea is that when you click on some text (or an edit button next to the text), an input is displayed along with save/cancel buttons. This enables the user to change the text to another value quickly and easily, in place.

Here’s what the final feature looks like.

The setup for this feature can be broken up into 3 parts:

  1. Directive logic
  2. Template for use with directive
  3. Usage on your view/partial


Normally the usage of a feature would be explained at the end (after the directive & template explaination), but in this case it is helpful to see how the directive is used before explaining it.

You need at least 3 directive properties:

  • inline-edit - the text to display initially to the user & the model value. It is an object. It is the value you’d normally write like this {{person.Name}}
  • on-save - the function in your controller that will save the newly inserted value
  • on-cancel - the value to revert to when the user clicks cancel

And the usage in markup looks like this…

<div inline-edit="person.Name" on-save="vm.updatePerson(person)" on-cancel="cancelEdit(person.Name)"></div>


The directive contains 3 notable functions, edit, save, & cancel.

The edit function is initialized when the user begins the edit process. This function start the edit process by showing the input and buttons, stores the initial value of the input (for use with the cancel button), and focuses the input.

The save function invokes handleSave which at runtime is the function name you pass to on-save. Therefore on click of the save button, the handleSave value is hit in its respective controller.

Lastly, the cancel function hides the inline edit elements and reverts the model value to the initial text value. You can also pass a function in the on-cancel directive attribute if you want to perform some logic in your controller on cancel.

Select boxes: You can also use select boxes with this inline edit directive. An example usage of this is: <div inline-edit="person.Country" preset-values="countriesArray" on-save="vm.updatePersonCountry(person)" on-cancel="cancelEdit(person.Country)"></div>

Essentially the usage is the same, aside from the preset-values attribute, which is an array of properties to fill the select box.

var app = angular.module('myApp');

app.directive('inlineEdit', inlineEditDirective);

inlineEditDirective.$inject = ['$timeout', 'config'];

function inlineEditDirective($timeout, config) {

    return {
        scope: {
            model: '=inlineEdit',
            handleSave: '&onSave',
            handleCancel: '&onCancel',
            presetValues: '=presetValues'
        link: function (scope, elm, attr) {
            var previousValue,

            scope.inputType = {
                settingValuesSelectbox: (scope.presetValues && scope.presetValues.length > 0) ? scope.presetValues : false

            scope.edit = function () {
                scope.editMode = true;

                previousValue = scope.model;

                if (scope.inputType.settingValuesSelectbox) {

                } else if (scope.model !== 'true' && scope.model !== 'false') {
                    $timeout(function () {
                    }, 0, false);

            scope.save = function (param) {
                scope.handleSave({ value: scope.model });
                scope.editMode = false;

            scope.cancel = function () {
                scope.editMode = false;
                scope.model = previousValue;
                scope.handleCancel({ value: scope.model });

            scope.selectChanged = function (param) {
                previousSelectVal = param;
        templateUrl: config.baseUrl + '/Templates/DirectiveTemplates/inline-edit.html'


    <div ng-show="editMode" style="display: inline;">
        <form role="form" name="inlineForm">
            <div ng-show="!inputType.settingValuesSelectbox">

                <div ng-class="{ 'has-error' : inlineForm.model.$invalid && !inlineForm.model.$pristine }">
                    <span ng-if="model == 'true' || model == 'false'">
                        <select ng-options="option as option for option in ['true', 'false']" ng-model="$parent.model" class="form-control input-sm inline-edit-selectbox"></select>
                        <button type="button" class="btn btn-default btn-xs" ng-click="cancel()">cancel</button>
                        <button class="btn btn-vtx btn-xs" ng-click="save($parent.model)" ng-disabled="inlineForm.$invalid">save</button>
                    <span ng-if="model != 'true' && model != 'false'">
                        <input class="form-control inline-edit-input input-xs" type="text" on-enter="save()" on-esc="cancel()" ng-model="$parent.model" required name="model">
                        <button type="button" class="btn btn-default btn-xs" ng-click="cancel()">cancel</button>
                        <button class="btn btn-vtx btn-xs" ng-click="save($parent.model)" ng-disabled="inlineForm.$invalid">
                            <span ng-hide="savingInProgress">save</span>


            <span ng-show="inputType.settingValuesSelectbox">
                <select class="form-control input-sm inline-edit-selectbox" on-enter="save()" on-esc="cancel()" ng-model="model" ng-change="selectChanged(model)" ng-options="option as option for option in inputType.settingValuesSelectbox"></select>
                <button type="button" class="btn btn-default btn-xs" ng-click="cancel()">cancel</button>
                <button class="btn btn-vtx btn-xs" ng-click="save(model)" ng-disabled="inlineForm.$invalid">save</button>
    <div class="editable-item-name" ng-mouseenter="showEdit = true" ng-mouseleave="showEdit = false">
        <div class="inline-edit-mode" ng-hide="editMode" ng-click="edit()">{{model}}</div>

        <a class="pull-left inline-edit-link" ng-click="edit()" ng-hide="editMode">
            <i class="fa fa-edit"></i>