Tuesday, January 2, 2018

Angular JS + Progressive Web App Service Worker

Nowadays AngularJS come less popular due the release of Angular 2+. But it's still a good choice for those developers, who don't want to work with TypeScript and NodeJS. In this tutorial I want to show you how to create an app, which is fully PWA friendly.
First, let's create a skeleton HTML and include the necessary Javascript files:
<!DOCTYPE html>
<html itemscope itemtype="http://schema.org/Product" ng-app="myApp">
 <head>
  <meta charset="utf-8" />
  <script src="js/angular.min.js"></script>
  <script src="app.js"></script>

 </head>
 <body ng-cloak ng-controller="MainController as vm">

 </body>
</html>

Next, create an app.js, and open it in your favourite editor and create the AngularJS application:

angular.module("myApp", [])
controller("MainController", function() {
    var vm = this;
});


Ok. Now we have a working Angular JS application skeleton, it's time to make it Progressive! Create a new Javascript block in your HTML file, and add these lines:

var CACHE_NAME = 'myapp-cache-v1';
var urlsToCache = [
 'index.html'
];

self.addEventListener('install', function(event) {
  event.waitUntil(
    caches.open(CACHE_NAME)
      .then(function(cache) {
        return cache.addAll(urlsToCache);
      })
  );
});

self.addEventListener('fetch', function(event) {
  event.respondWith(
    caches.match(event.request)
      .then(function(response) {
        if (response) {
          return response;
        }
        return fetch(event.request);
      }
    )
  );
});

self.addEventListener('activate', function(event) {
  var cacheWhitelist = [CACHE_NAME];
  event.waitUntil(
    caches.keys().then(function(cacheNames) {
      return Promise.all(
        cacheNames.map(function(cacheName) {
          if (cacheWhitelist.indexOf(cacheName) === -1) {
            return caches.delete(cacheName);
          }
        })
      );
    })
  );
});

Now, your task is only to modify the urlsToCache array. You must put all the paths and urls you want to cache: Javascript & CSS files, HTML templates, AngularJS routes, etc. Finally, add these lines into your HTML file:

<script>
    if('serviceWorker' in navigator) {
   navigator.serviceWorker.register('./sw.js', { scope: '/' })
    .then(function(registration) {
     var serviceWorker;
     if (registration.installing) {
       serviceWorker = registration.installing;
     } else if (registration.waiting) {
       serviceWorker = registration.waiting;
     } else if (registration.active) {
       serviceWorker = registration.active;
     }

     if (serviceWorker) {
       console.log("ServiceWorker phase:", serviceWorker.state);

       serviceWorker.addEventListener('statechange', function (e) {
      console.log("ServiceWorker phase:", e.target.state);
       });
     }
    });
   navigator.serviceWorker.ready
    .then(function(registration) {
     console.log('ServiceWorker registration ready', registration);
    });
    }

</script>

This code now testable, but it's working only on an HTTPS server. For local development I recommend you my mini-http-server application.

If you use Google Chrome, you have to start it with

--user-data-dir=C:/tmp --ignore-certificate-errors --unsafely-treat-insecure-origin-as-secure=https://localhost

With this option Chrome'll skip checking of untrusted certifications.

Configure and use VSCode for Java web development

Embarking on Java web development often starts with choosing the right tools that streamline the coding process while enhancing productivity...