Learning to Make a Progressive Web App

October 01, 2017

So while reaching out via email, I started to notice I was taking too long writing those emails. I decided to try composing some email templates and save them as drafts so when a reach-out opportunity arrises I could send an email much faster.

Now I did not want to make my emails spammy, so I decided I would personalize them. I started by making email templates that were simply an outline of what I think the body of the email should have depending on the situation. Here is an example:

Greeting

A sentence with my name and what I do

The purpose of the email

One or two links I think were appropriate

Contact info

I performed a Google search to see if there were any apps or browser plugins to help me save the templates to I can reuse them instead of having them saved as drafts.

I found gmail actually has this feature build in. It is called Canned Responses. But there's a problem. It only works on desktop. Oh ma...an!

Back in the days, I used Outlook. And I knew Outlook also supported saving emails as templates. But only for desktop. Perhaps nowadays this feature had been added, but I was not about to switch email client in my Samsung Galaxy... because I use the Galaxy Gear smartwatch and I cannot reply to emails using my smartwatch if I do not use Samsung's email app (OK I seldom send emails this way, but still).

What... to... do?

How about make a web page with a list of email links that already have the body and subject. That way I can use it in my desktop, tablet, and smartphone. Cool!

Open up emacs. Connect to my VPS where I keep an nginx server running all the time. Create a folder called email-templates. Create index.html. Add a subdomain to nginx. Voilà!

How do you write an email link? CSS-Tricks to the rescue. Mailto Links

Added an anchor with subject and body. Click, Tap, Tap. It works!

Let's get some templates online to populate this webpage. Oh no!

A quick search for canned emails on Google landed me at http://cannedemails.com/.

Wha...at! Someone already did this? Oh hell's nah! Time to step it up.

Bust out the PWA

Two things I want my web-app to do that this website doe not provide:

Offline availability

Ability to create and save templates

Now, for the past few months, I had been tumbling down the rabbit whole of progressive web apps. I found this while optimizing my websites for speed. I stumbled upon the Lighthouse plugin. Ran a quick test and then cried.

After spending days improving my PageSpeed score and getting it to 98%, Lighthouse gave me a RED 36% for Progressive Web App. Progressive what tha what?

I found out about the benefits of developing websites that can be installed as apps in mobile devices, what Google calls Progressive Web Apps or PWAs.

OK, so a few tutorials later and a few npm serve commands, I was hooked. So when the opportunity came to make a PWA for real-world use, I said; Hey, let's get it done.

The Front-End

The ploriferation of Javascript use over the past years has been tremendous, and for me overwhelming. I started designing and developing websites using a LAMP/LEMP stack. Then I learned to make hybrid apps using Cordova and jQuery Mobile for front-end and Mongo for back-end. I then switched jQuery Mobile for Ionic/Angular.

I've dabbled with Meteor, React, React Native, Monaca, and Xamarin but I was starting to feel both confortable and productive with Angular.

So when it came time to select a tool to build my PWA, I went with Ionic/Angular.

The Back-End

In the good'ol days I would probably have gone with MySQL. But hey, I need offline support.

Next contender was Mongo DB, simply because I had used Facebook's Parse as the API. But now that Parse is dead, well let see if there is something new and exciting.

As I researched backends to use with Angular, I found a tutorial that showed me how to deploy my Angular web app to Google Firebase. Now I was familiar with Firebase and in the past what kept me from using it was its lack for server side logic (functions or what Parse would call Cloud Code). But I saw that Firebase had added functions, and Firebase also has offline support, so I decided to give them a try again.

Goals

Alright, so I want the app to have users login and create their email templates and possibly have users share their templates. But there is alot to consider here. So I toned it down to the following

Primary Goal

Build a PWA that where me and my wife can save email templates

Secondary Goal

Add the ability to share the email templates by marking them public

Third Goal

Ability to register to use the app

Getting Familiar with Ionic/Angular

In this section, I will give a summary of the structure of Ionic/Angular app that relates to the making of this app. I will get into more details later.

In this case I chose to use the Ionic Super template so I can get familiar with Login and Signup processes.

> ionic start cannedemails super
> cd cannedemails

At first glance, I identified the following pages that I think I will use in this app.

Tour Page

Sign Up/Login Page

Login Page

Sign Up Page

Items Page

Item Page

I also dug a little into the code to get a feel for the API and I identified the following structure:

Pages talk to Providers

Some Providers talk to Models

Some Providers talk to external APIs

Some Models talk to Providers

For example.

sign-up page talks to API provider to perform authorization

list-master page talks to items provider which talks to the item model which talks to the API provider

Coming from PHP and Yii Framework. I am well aware of the many aspects of development. From MVC, to Migrations, to Unit and Functional Testing, to Debugging server-side with XDEBUG and client-side in the development console.

By looking at the table of contents in these books, I got really excited when I saw similar concepts in the world of Typescript and Angular Framework.

END of DAY 1

Wireframes

Looking at all that potential is really exciting; and exhauting at the same time. So how about building the app in Adobe XD so I can show it to my wife!

I might use the Materialize Theme for Ionic. So I will prototype using the Materialize UI Kit provided in Adobe XD. If an UI component is missing from the kit, then I will simply recreate it by referencing the components from the Ionic website.

I start with the Tour pages.

Moving onto the Login/Signup page.

Oh man! I nearly went into designing the logo. I'll simply note that I am thinking of a can top with an email icon in the center. For now, let me just go to flaticons.com and get some envelop look icon and use it as a placeholder.

CreateReadUpdateDelete (CRUD)

Now that I have a basic flow for the app, I can start creating the Models (CannedEmails) and CRUD pages.

The ionic super template already comes with CRUD pages, but it is saving the data in memory, so as soon as we close the app, we loose the data. I want the data to be permanent.

We can store the data permantly in one device by using localStorage. But in the future I want to also have the app sync my canned emails to all the devices where I log in, so maybe starting by using a remote storage location may be a good idea.

I can also start with the localStorage solution and then add the remote storage feature later.

At this point I performed a little research on adding a backend to Ionic. I found that Firebase offers offline storage and there are modules that I can add easily to Ionic to integrate Firebase. So I decided to go for Firebase as the backend and storage.

Angular App Architechture

The wirframing process allowed me to get familiar with the functionality and architecture of the super app. But I do not have a clear picture of the architecture of an angular app, so I started with the angular.io documentation and drew my own achitecture diagram to help me understand the angular app architecture.

I got stuck at Modules and Injectors. So I'll stop here and continue next day.

END OF DAY 3

Well understanding the Angular Architure was a trip in a rabbit hole. I started with the intention of simply making a top level architecture diagram, but I did not find it as useful as I thought it would be since at that level the underlying structure is quite involved.

I found the Component Architecture easy to understand. But Injectors and Modules are more way more involved than Components.

With just the component architecture, the angular framework would just be a javascript templating engine. Most of the magic happens in Injectors and Modules, so I decided to add more details to the architecture diagram by including the Injector and Modules.

Frustrations

Following 5-minute tutorials, and even 1-hour tutorials is nice. However, deviate slightly from the tutorial, and you quickly find out you need to pay close attention. Then when you want more details, the tutorials fail you. Waaa!

The book I ordered about Angular Firebase was cancelled. F*ing great!

Firebase

A great source of frustration came from integrating Firebase. The tutorials say the app will have basic authentication, but most don't cover logging out and persistent login. I concider those two features basic and thought it would be included in the tutorial.

Being a newcomer to the world of Angular 4 and Firebase, here are the concepts you really need to grasp before diving into code:

Typescript (syntax, code smells, new features compared to Js)

Angular (App Architecture)

Observables (this is the crux of making an app that connects to external APIs)