Ionic Framework as a Web Site

Oh iOS 9, I’m not going to miss you when iOS 10 drops. But with Apple’s pattern lately of breaking more and more Cordova/Hybrid compatibility in their new iOS releases, WkWebView in iOS8 and now Url’s with hash’s\window.location in iOS9. When Apple uses the slogan “Nothing’s changed, but everything” it should be “Nothing’s changed, but our degraded support for your Hybrid applications”.

Sorry I’m a little sore. It wouldn’t be so bad if their review times weren’t 7 days long (in the best cases lately) and asking for a expedited review was akin to asking your overly protective mother if you can stay out late after the movie……wait off track again sorry, gotta focus.

The above is the reason why Resgrid launched “Web Edition’s” of our mobile apps. The same app (more or less) as you get through the store but delivered via the browser, We are eagerly awaiting Ionic Lab’s Deploy to be released and available to be used on Store applications. Ionic if you need any testers were willing Smile.

Ionic doesn’t recommend using the framework for websites, it’s specifically designed for high performance hybrid mobile applications. But there if very little standing in the way for you to turn your Ionic application into a web application. But why would you want to do this?

  1. An Edge/Trial/Free Version of your app
  2. An online demo
  3. Supporting Desktop/Laptop users

For Resgrid we wanted a web edition that we can updated on the fly or use automated deployments.

Cordova, Plugins and Device Access

The first area you will run into issues is if your trying to access Cordova. In a web site you will not have access to the Cordova (as there is no ‘device’ for it to broker calls to). For Resgrid we had only a few instances where we needed an actual Cordova device, some of them where:

  1. Check if a device is an iPhone or Android
  2. Opening a file using the File Opener
  3. Getting the device UUID/UDID (via a plugin)

So here’s a simple Angular service we wrote to give us a check, isPhone(), before we do any device access or show features that require a device.

(function () {
    'use strict';

    angular.module('responder.utils').factory('deviceUtils', deviceUtils);

    deviceUtils.$inject = ['$q', '$timeout', '$ionicPlatform', '$cordovaDevice'];
    function deviceUtils($q, $timeout, $ionicPlatform, $cordovaDevice) {

        return {
            getDevice: function () {
                if ($cordovaDevice)
                    return $cordovaDevice.getPlatform();

                return "Web";
            },
            isPhone: function () {
                if (typeof (cordova) !== "undefined")
                    return true;

                return false;
            },
            isWinPhone: function() {
                if ($cordovaDevice)
                    if ($cordovaDevice.getPlatform() == 'WP8' || $cordovaDevice.getPlatform() == 'Win32NT' || $cordovaDevice.getPlatform() == 'WinCE')
                        return true;

                return false;
            }
        }
    }

}());
WebSQL\SQLite Plugin

Oh SQLite, your awesome, but not all at the same time. If your using SQLite as a backend storage system you can fall back to WebSQL without any API changes, but there’s a catch, WebSQL is deprecated and unsupported in Firefox and IE. Chances are it will be unsupported more and more as time goes on.

The solution? YDN-DB. YDN-DB is an abstraction over a number of different database implementations. In our implementation below we tell YDN-DB the order of priority for it to use as a backing database store in the options {mechanisms} array. We’ve told it to use SQLite first, if that’s not available/support use IndexedDB, then WebSQL, then NoSQL LocalStorage and finally memory.

(function () {
    'use strict';

    angular.module('responder.services').factory('localDbService', localDbService);

    localDbService.$inject = ['$q'];
    function localDbService($q) {
        var db;
        var valid = true;

        return {
            init: function () {
                var deferred = $q.defer();

                // Order of preferred storage mechanisms.
                var options = { mechanisms: ['sqlite', 'indexeddb', 'websql', 'localstorage', 'memory'] };

                try {
                    db = new ydn.db.Storage('ResgridResponder', dbSchema, options);

                    db.onReady(function (err) {
                        if (err) {
                            console.log(err);
                            deferred.reject(err);
                        } else {
                            deferred.resolve();

                            // Occurs when the database halts and catches fire!
                            db.addEventListener('fail', function (event) {
                                var err = event.getError();
                                console.log('connection failed with ' + err.name + ' by ' + err.message);
                                db = null; // no operation can be placed to the database instance
                                valid = false;
                            });

                            // Occurs when a database error (i.e. a query error) occurs
                            db.addEventListener('error', function (event) {
                                var e = event.getError();
                                // common errors are AbortError, ConstraintError and UnknownError (possibliy for Quota exceed error).
                                // log error for debugging
                                console.log('connection failed with ' + e.name);
                            });
                        }
                    });
                } catch (e) {
                    console.log("Unsupported browser, cannot use WebSQL");
                    valid = false;
                    deferred.reject('Unsupported');
                }

                return deferred.promise;
            }
        }
}());

With these changes, replacing SQLite and check to ensure we are on a phone before trying to use any Cordova or Cordova Plugin functionality, we were able to quickly use Gulp to build our site and deploy it to a Azure Web App.

Resgrid is a SaaS product utilizing Microsoft Azure, providing logistics, management and communication tools to first responder organizations like volunteer fire departments, career fire departments, EMS, search and rescue, CERT, public safety, disaster relief organizations, etc. It was founded in late 2012 by myself and Jason Jarrett (staxmanade).

About: Shawn Jackson

I’ve spent the last 18 years in the world of Information Technology on both the IT and Development sides of the aisle. I’m currently a Software Engineer for Paylocity. In addition to working at Paylocity, I’m also the Founder of Resgrid, a cloud services company dedicated to providing logistics and management solutions to first responder organizations, volunteer and career fire departments, EMS, ambulance services, search and rescue, public safety, HAZMAT and others.


One thought on “Ionic Framework as a Web Site”

Comments are closed.