Category: JavaScript

CSS Box Model broken down

What is the CSS Box Model.

CSS Box Model

When a web page is rendered, the browser's rendering engine will display each HTML elements as a rectangular box.

Every rectangle is composed of a margin, border, padding and the element. If you open google chrome browser's console and inspect an element, go to the right column and scroll down until you see a box.

css box model

How to calculate the size of the box?

width = content width + padding-left + padding-right + border-left + border-right 
height = content height + padding-top + padding-bottom + border-top + border-button

note: The margin doesn't affect the size of the box, but it affects other content interacting around the box.

You can control how the size of the box it calculated with box-sizing.
The box-sizing CSS property sets how the total width and height of an element is calculated.

syntax:

box-sizing: content-box | border-box

See full example below for a better understanding.

See the Pen
Example css model box
by Jose Mendez (@jomendez)
on CodePen.

From the MDN:

Box model content area.

The content area, bounded by the content edge, contains the "real" content of the element, such as text, an image, or a video player. Its dimensions are the content width (or content-box width) and the content height (or content-box height). It often has a background color or background image.

If the box-sizing property is set to content-box (default) and if the element is a block element, the content area's size can be explicitly defined with the width, min-width, max-width, height, min-height, and max-height properties.

Box model padding area.

The padding area, bounded by the padding edge, extends the content area to include the element's padding. Its dimensions are the padding-box width and the padding-box height.

The thickness of the padding is determined by the padding-top, padding-right, padding-bottom, padding-left, and shorthand padding properties.

Box model border area.

The border area, bounded by the border edge, extends the padding area to include the element's borders. Its dimensions are the border-box width and the border-box height.

The thickness of the borders are determined by the border-width and shorthand border properties. If the box-sizing property is set to border-box, the border area's size can be explicitly defined with the width, min-width, max-width, height, min-height, and max-height properties. When there is a background (background-color or background-image) set on a box, it extends to the outer edge of the border (i.e. extends underneath the border in z-ordering). This default behavior can be altered with the background-clip css property.

Box model margin area.

The margin area, bounded by the margin edge, extends the border area to include an empty area used to separate the element from its neighbors. Its dimensions are the margin-box width and the margin-box height.
he size of the margin area is determined by the margin-top, margin-right, margin-bottom, margin-left, and shorthand margin properties. When margin collapsing occurs, the margin area is not clearly defined since margins are shared between boxes.

What if these values are not declared?

If margin, padding or borders are undeclared, they are either zero or the browser's default value.

See the box model with your own eyes.

You can visualize the box model in your page by opening the chrome developer tool and inspect the body of your page, add temporarely the following code:

* {
border: 1px solid red !important;
}

visualizing the css box model

Simplistic CRUD ionic 5 firestore TODO app example

Simplistic CRUD ionic 5 firestore TODO app example

This is a very simplistic CRUD (Create, Read, Update, Delete) Created with ionic 5 and firestore (database).

You can download the source code here.

Note:
I used this design as inspiration: https://dribbble.com/shots/4782162-To-Do-App-Concept-Minimal.

The idea here is to illustrate how to create a simple CRUD with firestore.

 Simplistic CRUD ionic 5 firestore TODO app example

Installation.

My advice is that you install nvm (to manage your node versions), here is tutorial step by step.

After you install nvm run the following commands:

nvm install 12

If everything went well you'll have installed node 12.0.0 .

Now you'll need to install ionic cli:

npm install -g @ionic/cli

Now is time to download the project and install it's dependencies.

git clone https://github.com/jomendez/ionic-5-crud-todo-with-firestore.git
cd ionic-5-crud-todo-with-firestore
npm install

Next step it to create a config file that will contain your firebase config keys here:

src/app/config/firebase.ts

If you are on bash you can use the following command:

touch src/app/config/firebase.ts

Assuming that you are familiar with firebase and already have an account, paste your configuration info into the firebase.ts file, it should looks something like this (This is just and example), If you are not familiar with firebase or doesn't have an account, I'll provide more information on how to do it bellow.

Example of configuration:

export const firebaseConfig = {
  apiKey: "AIzaSwERfdilPYtcNDfvFR6x944EowerdfghfSDFsfg",
  authDomain: "crud-456657.firebaseapp.com",
  databaseURL: "https://crud-456657.firebaseio.com",
  projectId: "crud-456657",
  storageBucket: "crud-456657.appspot.com",
  messagingSenderId: "10130122343423",
  appId: "1:1013012342277:web:sd9f8sd8fs8dfs89df89s",
  measurementId: "G-3FGJ34GFGJK"
};

How to get your firebase configuration.

Go to https://firebase.google.com/ and login with your account or create a new one.

Click on create a web app (This is the screen that you'll see the first time you create a projects):

image

Or add a new project (If you have already other projects created):

image

Enter the name of your project, accept the terms, and finish the other two steps on the wizard:

image

Next you'll see something like this, from here you can grab the configuration key.

image

If you missed the previous screen you can always go to the cog wheel on the left side panel, and click on project settings.

image

Now scroll down to the Your App section and click on config radio button, and copy the code highlighted on the image bellow, and paste it on the firebase.ts file.

image

Create web apps with Webpack

webpack banner

A simple but powerful project to rapid prototyping and development of front-end apps, with scss (optional), pug (optional), ES7, webpack (bundlefy, uglyfy, etc). Very useful to create static websites or apps, without having to worry about setting up the environment.

You can get the source code free on Github.

Features.

  • Modern Technologies: Full support for HTML5, PUG, JavaScript (Vanilla and ES7) and CSS (Sass, scss and PostCSS).
  • Built-in Server: Local development server with live reloading.
  • Performance Tuning: CSS and JavaScript transpilation, bundling, autoprefixing, and minification.
  • Image Optimization: Optimizes images for loading speed.
  • Favicon Generation: Automatically generates all favicons for Web, Apple and Android devices from one image file.
  • Code Linting: Full support for JavaScript (ESLint) and CSS (StyleLint) linting.
  • Setup Wizard: Optionally install helpful libraries and snippets .including:
    • jQuery.
    • Google Analytics.
    • FTP deployment process.
  • Cutting Edge: Uses Webpack for processing and bundling your code.
  • Deployment: Built-in support for deployment via FTP.

Requirements.

  • Node.js (developed with node 12).

Installation Steps.

Clone repo:

 git clone https://github.com/jomendez/simple-webpack-boilerplate &&
 cd simple-webpack-boilerplate &&
 rm -rf .git && git init
  1. Run npm install.
  2. Then run npm run setup to configure the app (include JQuery, etc).

In this step you'll be able to setup your google analytics, enable jquery, setup (optional) an FTP for deployments.

image

  1. Run npm run dev to open a browser and lunch a local web server with live-reload.
  2. Run npm run build build for production (./dist folder).
  3. Run npm run deploy to deploy your code to your FTP.

If everything went well (npm run dev)...

You browser should open a new tab and you should see something like this:

image

Quick example.

It is recommended to create a new page within the src folder or use the one that comes with the example page.pug to start adding your content.

image

Then you can go to src/js/app.js file and add the following lines:

const page = require("../page.pug");
document.querySelector('container').innerHTML = page();

The code above is going to transpile the pug file this particular case (but it can be an html file).
Then we will insert the content of the page into the container tag on the index.html.

My interactive portfolio

jose mendez portfolio

About the author

I describe myself as a passionate Front-end developer, focusing on create, test, and optimize full web apps with compelling user interfaces that runs in web browsers on any device, from desktop computer to tablets and cellphones, therefore, my principal allies are javascript, html, css, and the browser's event loop. That's why you will always find me learning and improving my skills to master those pillars and it's surrounding frameworks and technologies, such as angular, nodejs, ionic, react, etc.

Goals

Some times I find it a little bit hard to interpolate/transmit the description above to recruiters and hiring managers, just with my online presence (before any interview or conversation). That's why my intention is that they just get it by seeing and interacting with this portfolio.

Thus I decided to create a portfolio/profile/interactive resume as a complement for my actual resume and Linkedin profile, in addition to that, also for this two reasons:

  1. To challenge my skills with css animations and interaction.

  2. To create a showcase and challenge myself in a cool framework that I was recently immersing: Threejs which is used to create 3d environments, interactions, etc. on the web.

I wanted to do something different for this project, so I thought... why don't I create a 3d interactive version of myself. I did a research on the internet and I found this article, about how to create an interactive 3D character with Threejs, and I used it as a guide to create my own 3d interactive character:

https://tympanus.net/codrops/2019/10/14/how-to-create-an-interactive-3d-character-with-three-js/

About the (portfolio/profile/interactive resume)

Now, the portfolio/profile/interactive resume can be broken down into 2 main parts:

  1. The get to know the non-technical side of the person, the activities that he likes more (the 4 inner buttons) click on the buttons to know more about the author and see the interactions and animations of the character...

jose mendez portfolio inner menus

  1. The more technical part, more like a resume, showing the technical skills, places he worked, some of his recent work (games, Ionic starters, etc.), featured blog posts, certifications etc.That you can access by clicking on the outer buttons, (placed in the corners)

Portfolio

You can navigate to the portfolio/profile/interactive resume here:

http://www.jomendez.com/portfolio/

Javascript is weird

javascript is weird

I mean, javascript could be weird for developers that are just starting with the language and mostly for developers that comes from other languages like C++ or C# for example.

There are certain areas of the language that cam blow your mind 🤯🤯
In this article we are going to see 5 examples, and keep it simple withing the ~2 min reading time.

Numeric separators

Lets take for example the following code:

const number1 = 2_0_0_0;
const number2 = 6_0_0_0;

console.log(number1 + number2);

What you think the result is going to be?

You can copy and paste the code on a browser developer console or you can play with it yourself on codepen.

The result is 8000, but why?

The thing is that the underscore (_) is a numeric separator for numeric literal. It is used to group digits to make long numbers more readable, for example:

1234567

1_234_567 <-- Therefore, it is more readable with the separator.

More info in this article.

Some weird types.

Another example is when you run the code typeof null

typeof null;
// result object

which incorrectly suggests that null is an object (it isn't, it's a primitive value).

well in this case it is not just a weird thing, it is a bug in the language that can't be corrected because it will brake other parts of the code.

There is a more deep explanation in this article.

Meanwhile...

 typeof NaN;
 // result number.

Is it weird that NaN — “not a number” is actually a number or is just me? On the other hand, NaN is not equal to itself.

console.log(NaN === NaN);
//evaluates false.

Functions.

In javascript a function can self-invoke it self IIFE (Immediately Invoked Function Expression) , so you can do declaration and execution on the same statement.

(function() { console.log('hello'); })();
//display 'hello'

As far as I know this only exist in javascript. It is quite useful, can be used to avoid variable hoisting from within blocks, protect against polluting the global environment and simultaneously allow public access to methods while retaining privacy for variables defined within the function.

You can learn more on this article

Reset an array

And last but not least, the most weird way of resetting an array, you can set the length property to cero: arr.length = 0;.

const arr = [1,2,3,4,5,6];
console.log(arr);
// displays [1, 2, 3, 4, 5, 6]

arr.length = 0;
console.log(arr);
// displays []

I hope you like it, and if you know any other weird thing specific of the javascript language please feel free to share it with us. 😉

javascript proxy – Querying arrays with more readable methods

javascript

javascript Proxy.

This a new feature introduced in the ES6 standard. The Proxy object is used to define custom behavior for fundamental operations (e.g. property lookup, assignment, enumeration, function invocation, etc).

The basics.

There are 3 key terms we need to define before we proceed:

  • handler — the placeholder object which contains the trap(s).
  • traps — the method(s) that provide property access.
  • target — object which the proxy virtualizes.

Here is a list of available Traps.

  • apply
  • construct
  • defineProperty
  • deleteProperty
  • get
  • getOwnPropertyDescriptor
  • getPrototypeOf
  • has
  • isExtensible
  • ownKeys
  • preventExtensions
  • set
  • setPrototypeOf

The list going on and on...

The syntax

let proxy = new Proxy( target, trapObject );

Quick example.

Let's see a quick example before we dive in into create our array query library.


class Student {
    constructor(first, last, scores) {
        this.firstName = first;
        this.lastName = last;
        this.testScores = scores;
    }
    get average() {
        let average = this.testScores.reduce( 
            (a,b) => a + b, 
            0 
        ) / this.testScores.length;
        return average;
    }
}

//instantiate the student class  
let john = new Student( 'John', 'Doe', [70, 80, 90] );

let johnProxy = new Proxy( john, {
   //we trap the get and print the property accessed 
    get: function( target, key, context ) {
        console.log( `john[${key}] was accessed.` );
        return john[key];
    } 
});

johnProxy.firstName;
//output.
//> john[firstName] was accessed.
//> <property content>

In this example we are just intercepting the properties called, for example johnProxy.firstName and printed it to the console, this could be used for debugging purpose in dev environments. We can do the same and intersect the 'set' and print a message to the console when we set the value on a property.

Let's create our query library.

It would be similar to write an assertion library, where you can use the name of the field you want to query withing the method's call instead of passing it as a parameter.

First let's create the assertion object.

Here we are going to define the assertion operations, our proxy object will return the objects based on this conditions:

let assertions = {
  Equals: (object, value) => object === value,
  IsNull: (object, value) => object === null,
  IsUndefined: (object, value) => object === undefined,
  IsEmpty: (object, value) => object.length === 0,
  Includes: (object, value) => object.includes(value),
  IsLowerThan: (object, value) => object < value,
  IsGreaterThan: (object, value) => object > value,
  EndsWith: (object, value) => object.endsWith(value),
  StartsWith: (object, value) => object.startsWith(value),
}

The proxy object.

Here we going to trap the get, of the target object to read the name of the property and make sure it starts with findWhere then we use the object field name we want to query, then the assertion (from the assertions above), So the syntax will looks something like this arr.findWhereNameStartsWith('Jo')

let wrap = arr => {
  const prefix = 'findWhere';
  let assertionNames = Object.keys(assertions);
  return new Proxy(arr, {
    get(target, propKey) {
      if (propKey in target) return target[propKey];
      var assertionName = assertionNames.find(assertion =>
        propKey.endsWith(assertion));
      if (propKey.startsWith(prefix)) {
        var field = propKey.substring(prefix.length,
          propKey.length - assertionName.length).toLowerCase();

        var assertion = assertions[assertionName];
        return value => {
          return target.filter(item => assertion(item[field], value));
        }
      }
    }
  })
}

Declare the object.

Next step is to declare the object and wrap it up with the proxy.

let arr = wrap([
  { name: 'John', age: 23, skills: ['mongodb', 'javascript'] },
  { name: 'Lily', age: 20, skills: ['redis'] },
  { name: 'Iris', age: 43, skills: ['python', 'javascript'] }
]);

Calling the methods

console.log(arr.findWhereNameEquals('Lily')) // finds Lily.
console.log(arr.findWhereSkillsIncludes('javascript')) // finds Iris.

The code above the first line will return the object where Property Name is equal to Lily and print it to the console, and the second line will return the object(s) where skills property includes javascript within the array.

Full source code.

Use the following code to play more with javascript proxy.

Things to notice.

Notice how we call the a method in the array that we didn't declared before arr.findWhereAgeIsLowerThan(30) we use the proxy to read this method, the expected syntax is findWhere + <array_field_name> + <assertion> this allow us to create custom queries using the array field name we want to query within the method name:

  • arr.findWhereAgeIsLowerThan(27);
  • arr.findWhereNameEquals('Lily');
  • arr.findWhereSkillsIncludes('javascript');

Wrapping up

With JavaScript proxy, you can wrap up an existing object and intercept any access to its attributes or methods. Even if they don't exist!

There are many real-world applications for Proxies:

  • Create SDK for an API.
  • validation.
  • value correction.
  • Revoke access to an object property/method.
  • Querying arrays with more readable methods (the main topic of this post).
  • property lookup extensions.
  • tracing property accesses.
  • Monitoring async functions.

Conclusions.

Javascript proxy enables a lot of possibilities to create more readable APIs where you can combine field names, assertions and create dynamics methods on the fly, however as you can see in the link below IE doesn't support it and this can be a downside to create code that needs to be supported by all major browsers. Unfortunately, it’s not possible to polyfill or transpile ES6 proxy code using tools such as Babel, because proxies have no ES5 equivalent.

For more info about javascript proxy and browser compatibility you can Learn more here

Add to Home Screen your ionic PWA

Add to Home Screen your ionic PWA

add-to-home-screen

One of the feature of Progressive Web Apps is the ability to add to home screen your application, in a mobile phone or on a desktop computer, if using Chrome (recommended) it handles most of the heavy lifting for you, and on Android, Chrome will generate a WebAPK creating an even more integrated experience for your users.

Starting on Chrome 68 (beta in early June 2018), Chrome will not automatically show the Add to Home Screen banner, instead, you must show it by calling prompt() on the beforeinstallprompt event.

Criteria to fire the "beforeinstallprompt" event

- The web app is not already installed
- Meets a user engagement heuristic (currently, the user has interacted with the domain for at least 30 seconds)
- Includes a web app manifest that includes:
   short_name or name
   icons must include a 192px and a 512px sized icons
   start_url
   display must be one of: fullscreen, standalone, or minimal-ui
- Served over HTTPS (required for service workers)
- Has registered a service worker with a fetch event handler

Note: Other browsers may have different criteria to trigger the beforeinstallprompt event, check their respective sites for full details: Edge, Firefox, Opera.

Show the add to home screen prompt

In order to prompt to the users the Add to Home Screen prompt, you need to:

1- Listen for the beforeinstallprompt event
2- Notify the user your app can be installed with a button or other element that will generate a user gesture event.
3- Show the prompt by calling prompt() on the saved beforeinstallprompt event.

let deferredPrompt;

window.addEventListener('beforeinstallprompt', (e) => {
  // Prevent Chrome 67 and earlier from automatically showing the prompt
  e.preventDefault();
  // Stash the event so it can be triggered later on the button event.
  deferredPrompt = e;
// Update UI by showing a button to notify the user they can add to home screen
  btn.style.display = 'block';
});

//button click event to show the promt
btn.addEventListener('click', (e) => {
  // hide our user interface that shows our button
  btn.style.display = 'none';
  // Show the prompt
  deferredPrompt.prompt();
  // Wait for the user to respond to the prompt
  deferredPrompt.userChoice
    .then((choiceResult) => {
      if (choiceResult.outcome === 'accepted') {
        console.log('User accepted the prompt');
      } else {
        console.log('User dismissed the prompt');
      }
      deferredPrompt = null;
    });
});

You can only call deferredPrompt.prompt() on the deferred event once, if the user dismissed it, you'll need to wait until the beforeinstallprompt event is fired on the next page navigation.

How to determine if the app was installed

To determine if the application was successfully added to the user's home screen once they accepted the prompt, you need to listen for the appinstalled event.

window.addEventListener('appinstalled', (event) => {
 console.log('installed');
});

Detecting with JavaScript if you app is launched from the home screen

if (window.matchMedia('(display-mode: standalone)').matches) {
  console.log('display-mode is standalone');
}

Safari

if (window.navigator.standalone === true) {
  console.log('display-mode is standalone');
}

Easiest way to test if the beforeinstallprompt event will be fired

Easiest way is to use Lighthouse to audit your app, and check the results of the User Can Be Prompted To Install The Web App test.

Practical example with ionic

For this example I going to use ionic, we are going to generate a PWA with ionic, for this example I assume you are familiar with ionic and you have installed it on your computer, if not, then you can read the here

Lets generate our ionic app:

After you create the ionic blank app, lets run ionic serve:

cd pwa
ionic serve

You should see something like this on your browser:

Open your application using google chrome, open the dev tool, go to audit and run the Progressive web app audit:

You'll notice that the app is only 45% PWA out of the box, we should make some changes first to comply with the requirements to trigger the beforeinstallprompt event:

Registering the service worker

Open the ionic app on your preferred IDE (I'll use Microsoft code) and go to ./src/index.html and uncomment this line:

<!-- un-comment this code to enable service worker
  <script>
    if ('serviceWorker' in navigator) {
      navigator.serviceWorker.register('service-worker.js')
        .then(() => console.log('service worker installed'))
        .catch(err => console.error('Error', err));
    }
  </script>-->

The another requirement is to have a manifest.json, fortunately ionic generates one for us:

{
  "name": "Ionic",
  "short_name": "Ionic",
  "start_url": "index.html",
  "display": "standalone",
  "icons": [{
    "src": "assets/imgs/logo.png",
    "sizes": "512x512",
    "type": "image/png"
  }],
  "background_color": "#4e8ef7",
  "theme_color": "#4e8ef7"
}

Now lets provide a fallback when JavaScript is not available by just adding a < noscript > tag on the index:

<noscript>
This application needs JavaScript to work, please enable JavaScript on your browser
</noscript>

With just that, we were able to go from 45 to 82:

Now we need to deploy our app to firebase hosting to be able to have HTTPS, and a 100 score on the lighthouse.

Install firebase tools

npm install -g firebase-tools

Initialize your site

$ firebase init

To deploy your site, run the following command from your project's root directory:

$ firebase deploy

For more info go to https://firebase.google.com/docs/hosting/deploying

Now you can sun the lighthouse tool and obtain a 100 score:

Capturing the event

Go back to the ionic app code, locate the pages folder on src/pages/home and edit the home.html and home.ts as follow:

home.html

<ion-header>
  <ion-navbar>
    <ion-title>
      Ionic Blank
    </ion-title>
  </ion-navbar>
</ion-header>

<ion-content padding>
  The world is your oyster.
  <p>
    If you get lost, the <a href="http://ionicframework.com/docs/v2">docs</a> will be your guide.
  </p>
  <button class="btn" ion-button full (click)="add_to_home(event)" *ngIf="showBtn" >Install</button>
</ion-content>

home.ts

import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
  showBtn: boolean = false;
  deferredPrompt;
  constructor(public navCtrl: NavController) {
    
  }

  ionViewWillEnter(){
    window.addEventListener('beforeinstallprompt', (e) => {
      // Prevent Chrome 67 and earlier from automatically showing the prompt
      e.preventDefault();
      // Stash the event so it can be triggered later on the button event.
      this.deferredPrompt = e;
      
    // Update UI by showing a button to notify the user they can add to home screen
      this.showBtn = true;
    });
    
    //button click event to show the promt
            
    window.addEventListener('appinstalled', (event) => {
     alert('installed');
    });
    
    
    if (window.matchMedia('(display-mode: standalone)').matches) {
      alert('display-mode is standalone');
    }
  }

  add_to_home(e){
    debugger
    // hide our user interface that shows our button
    // Show the prompt
    this.deferredPrompt.prompt();
    // Wait for the user to respond to the prompt
    this.deferredPrompt.userChoice
      .then((choiceResult) => {
        if (choiceResult.outcome === 'accepted') {
          alert('User accepted the prompt');
        } else {
          alert('User dismissed the prompt');
        }
        this.deferredPrompt = null;
      });
  };

}

Test in your browser

To test the functionality, we could make some changes on chrome to force to trigger the event (taken from here https://stackoverflow.com/a/50626433/4320602)

For security reasons, as others have written as well, browsers don't allow you to manually trigger the install event.

However, there is a way you can test it yourself. Go to chrome://flags and enable "Bypass user engagement checks"

This will kick off the prompt so you can test.

now run your app and click on the install button, you should see something like this:

Now the app will run as standalone app:

Happy coding,
Cheers

Ionic 2 google signin Error 10 with firebase

Ionic 2 google signin Error 10 with firebase

The mysterious Error 10

I hope this article helps to clarify and find a solution quickly to the Error 10 using ionic 2 framewrok with firebase sign in and cordova-plugin-googleplus. I was developing an Ionic 2 application "quiz dev" to create a playful platform for developers to practice and improve their skill through quizzes, based on the spaced repetition approach. I wanted to provide the user the ability to sing in into the application using their google account.

error 10

The issue

The point is, that I've spend 2 or 3 days trying to figure out the error 10 I was receiving once I deployed to the Android Play Store. I followed the official documentation of Ionic https://ionicframework.com/docs/native/google-plus/

I installed the cordova-plugin-googleplus and implemented the plugin (I going to skip high level details, for more information refer to the documentation provided here)
 

  this.googlePlus.login({
        'webClientId':'#############-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com',
        'offline': true
      })
          .then(res => {
             //logged in
              ...
          })
          .catch(err => {
              alert("There is an error " + JSON.stringify(err));
          });

 

After that, I signed my debug.apk following the steps here, this is the google official documentation, then I get the SHA-1 fingerprint certificate that is going to be needed to setup the firebase project, you can do it via cmd following these steps. The result is going to be something like this:
sha-1 fingerprint certificate

I had set up a Firebase project, following the steps here https://chriztalk.com/ionic-2-firebase-google-authentication/

The headache

At this point installing the application in my device in release or debug mode, everything was working properly. Then I decided to deploy it to the google android app store. When installing the app from the android app store I wasn't unable to login with my google accounts, the previous code to handle the google sign in was entering in the catch section and showing an alert with error 10
 

 
          .catch(err => {
              alert("There is an error " + JSON.stringify(err));
          });

The solution

After spending hours and hours trying to figure out what the issue was, I realize that there is an option when you are setting up your application in the google app store that ask you if you want to sign your apk in the store. After you say yes it shows you a message like this:
google app store apk sign
 

the real solution is to go to Release Management/App signing section and get the SHA-1 fingerprint certificate and include it in your Firebase project
 
app signing google android app store

Go to your Firebase project configuration and add you SHA-1 fingerprint and it will do it
 
firebase add sha-1 fingerprint

Final thought

I really hoe this save you a lot of time of banging your head against the wall.

Here is a demo of the app, you can from android to ios here. The is the application in the android app store in case you are interested https://play.google.com/store/apps/details?id=com.evolutionsys.quiz&hl=en

Quick Introduction to VueJS

vuejs

What is Vuejs?

What makes VueJs special is the fact that was designed to be incrementally adoptable, the core is dedicated to the view layer only but you can combine it with other libraries in order to create great single pages apps. Is very versatile and flexible yet lightweight, there is also components that allows you to handle routes and AJAX requests, hence is able to provide high quality results from a little gadget to a more complex SPA.

Why chose Vue.js?

  • The documentation is so good that it is the only tutorial you will need to understand and be able to dominate Vue.js efficiently.
  • The Vue.js community is growing.
  • Solutions through libraries and plugins well supported.
  • The way Vue.js do the things allows you to produce great code, efficient as well as readable.

Comparison with other frameworks

Vue.js vs React

Similarities:

  • Uses a Virtual DOM
  • Reactive and composable view components
  • Focused on the core library, so global state management and routing are delegated to third libraries

Differences:

  • Vue.js offers better performance than React, As you can see here.
  • In React all the UI components are represented rendering functions using JSX. In the other hand Vue.js provides render functions, provides support for JSX and also as default offers declarative templates (very readable by the way).
  • The ecosystem around custom renders makes React a winner in this aspect.
  • In matters of CLI Vuejs got leverage because of the limitations of React in this area, related with the lack of configurations.
  • Before to start working with React you should be familiar with JSX and ECMAScript 6, because most of the examples out there uses It, in the other hand Vuejs is more simple, to get it running you just need a single script on your page.

Vue.js vs Angular 1
Similarities:

  • Vue.js in an early stage of development inspire in the Angular syntax (e.g. v-if vs ng-if).

Differences:

  • Vue.js is way much simpler than Angular 1. A newbie is able to write functional code in a day with Vue.js, with angular, the learning curve is more higher.
  • Angular 1 ‘forces’ you to build the app under a specific and non-so flexible structure. Vue.js in the other hand is more flexible and modular.
  • Vue.js enforces a one-way data flow between components while Angular 1 uses two-way binding between scopes.
  • Vue.js offers better performance than Angular 1 because Angular one uses dirty checking with a cycle digests this can affect the performance.

Vue.js vs Angular 2:

Similarities:

  • Performance is equal because both are very fast.
  • Both are well suited for Enterprise environments.

Differences:

  • Vue.js is more flexible than Angular 2 in terms of the app architecture. Angular has a well defined architecture, Vue.js is more simple.
  • In terms of learning curve, Vue.js is extremely low while Angular 2 is too steeper.

To see more comparison of VueJs and other frameworks, you can go here:
https://vuejs.org/v2/guide/comparison.html

Simple app example with Vue.js.

Let's create an simple object in javascript

 
var example = {
message: ‘Hi Vue’
}

This is going to be the template

 
<div id="container">
{{message}}
</div>

Vue in action, binding the template with the object:

 
new Vue({
el: '#container',
data: example
})

Here is a working example

 
Let’s see an example making use of a Vue.js directive: v-for:

This is the html template:

 
<html>
 <head>
<script src="./vue/dist/vue.js"></script>
 </head>
<body>
 <div id="app-example">
 <p v-for="human in people">                        
 {{ human.name }}
 </p>
 </div>
</body>
<script src="./app/myapp.js"></script>
</html>

Binding the template with the data

 
var app = new Vue({
  el: '#app-example',
  data: {
    people: [
     {name: 'albert'}, 
     {name: 'john'}, 
     {name: 'justin'}
     ]
  }
});

Here is a working example:
 

More examples can be found here: https://vuejs.org/v2/guide/, the introduction guide to Vue.js is one of the best tutorials you'll find.

Let's see another example, this time we are going to create a custom filter to reverse the text:
 

Here is an example where I use more concepts like, filters, methods, computed, the code is commented but if you don't understand the concepts and how it works you can visit the Vue official documentation, or see this video from Egghead:
https://egghead.io/courses/develop-web-apps-with-vue-js

Introduction to Reactive programming RxJs

 
Reactive programming is a general concept that you can find in any language, it is often associated with event driven UI, asynchronous programming with observable, where you can subscribe to events. Reactive Extensions (abbreviated Rx*) provides libraries for a wide variety of programming languages, including JavaScript (RxJS). RxJS it precisely that, an extension/library for JavaScript.
 
Reactive programming RxJs

  • What is Reactive programming RxJS?
  • But wait, what is an observable?
  • Anything can be a stream
  • Where can I use RxJs?
  • Try yourself
  • RxJS Observables vs Promises
  • RxJS integration with AngularJS.
  • Differences between RxJs and Knockout
  • Conclutions

What is Reactive programming RxJS?

Reactive programming RxJS or Reactive Extensions for JavaScript is a reactive streams library that can be used in the client-side in the browser or server-side with Node.js. to work with asynchronous data streams. From the perspective of JavaScript let’s analyze the last three words of the previous sentence: asynchronous – data – streams.
Asynchronous – Is the fact of calling a function and then register a callback when results are available, this way we are notified about the returning of that function and been able to continue with execution avoiding non responsive behavior in our page.
Data – Raw information represented by any data type: Number, String, Objects.
Stream – Data made available over time meaning that you don’t need the presence of all the information to start using it for example mouse clicks, user inputs, database queries or just the call to an API.

But wait, what is an observable?

Observable is a JavaScript implementation of the observer pattern (also known as ‘publish/subscribe’).
The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods.
It is mainly used to implement distributed event handling systems.

Anything can be a stream.

Taken from this great article of Gerard Sans.
Asynchronous data streams are a pretty old concept, it exists since Unix and take different names and behavior depending on the environment for example in Node.js they are called ‘streams’, ‘pipes’ on Unix and ‘async pipes’ on Angular 2.
reactive programming: programming is called reactive when you are working with Asynchronous data streams.
Using RxJS asynchronous data streams can be represented through Observables and manipulate those streams with different operators as if they were simple collections of data. Next section has some examples.

Where can I use RxJs?

Creating and subscribing to simple Observable sequences

First include rx.js file in your code, you can use a CDN https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.0.3/Rx.js:

<script src="rx.js"></script>

If using Node.js:

var Rx = require('rx');

Lets create a very simple example so you get the idea of how it works.
For this we are going to create a textarea (the stream acting as event generator) we are going to show to the user what we are writing in the textarea plus a fixed text (this is the reaction). This is going to looks like a data-binding between the textarea and the label.

<textarea></textarea>
  <p>
    <strong>Text:</strong>
    <code id="text"></code>
  </p>

 
const text = document.getElementById('text');
const area = document.querySelector('textarea')

const content$ = Rx.Observable
  .fromEvent(area, 'keyup') // each `keyup` throws an event on the stream
  // shows the content of the text area concatenated with the string ‘Fixed text’
  .map(e => e.target.value.trim() + ' Fixed text');

The suffix $ on the variable named ‘content’ it used to indicate that the variable is a data stream.
So, the data stream ‘content$’ will launch a new event each time the user inputs a new letter. The correct way to react to this constant stream of data is through the function “subscribe()” like this:

 
content$
  .subscribe(text => {
    console.log(`The textarea content is: ${text}`)
    text.innerText = text;//print the text.
  });

Now that we got the idea lets implement something more practical like a "word counter", in order to obtain the amount of words, we need to update the stream and update the user interface to show how many words are written. To do this we need the function ‘map()’ which is one of the many operators provided by RxJS (a full list of RxJS operators can be found here):

 
content$
  .map(content => content.trim().split(' '))// make the string into an array of words
  .map(wordList => wordList.length)// count the array elements
  .subscribe(totalWords => {
     text.innerText = totalWords
  })

Each step is transformed into stream and return a modified object to the next step. Finally we are going to use the function ‘subscribe()’ where we indicate what is going to be the reaction, in this case, the reaction is to update the user interface to show the amount of counted words.

Try yourself (full code):

I recommend you to read this tutorial for better understanding of the subject:

The introduction to Reactive Programming RxJs you've been missing

What operator to use

 

RxJS Observables vs Promises

Promises is a concept from javascript async programming. Basically the Promises give an abstracted help to work with asynchronous matter’s inside the apps. The promise is the eventual result of an asynchronous data stream task. For better understanding read this and analyze the example code text taken from here:

“The primary way of interacting with a promise is through its then method, which registers callbacks to receive either a promise’s eventual value or the reason why the promise cannot be fulfilled. You can create them very easily where the constructor has two functions, resolve and reject which resolves the value or rejects it for a given reason “

  • Observables are cancellable. Observable also has the advantage over Promise to be cancellable. If the result of an HTTP request to a server or some other expensive async operation isn't needed anymore, the Subscription of an Observable allows to cancel the subscription, while a Promise will eventually call the success or failed callback even when you don't need the notification or the result it provides anymore.
  • The main difference here is that Promises in order to be able of retry the call, the caller must have access to the original function that return the Promise. In the other hand Observables are cancellable and the API provides operators to retrieve them (‘retry’ function).
  • A Promise handles a single event when an async operation completes or fails.
    Note: There are Promise libraries out there that support cancellation, but ES6 Promise doesn't so far.

RxJS integration with AngularJS.

You may write a custom helper function to integrate this two but as you also may expect this task is already done. A library called rx.angular.js is in charge of this interoperability. Let’s analyze an example of using DOM-events:
To be able of use DOM-events we are going to use Rx.DOM, an HTML DOM bindings for RxJS provided by rx.angular.js. The next code is a feature to detect the time of inactivity of the user.

 
mergedStreams = rx.Observable.merge(  // mergin all the events coming from the user
rx.DOM.keydown(document), // keystrokes
rx.DOM.click(document), // mouse click
rx.DOM.mousemove(document), //mouse move
rx.DOM.scroll(document), //scroll
rx.DOM.touchstart(document) // taps
);

var idleStream = mergedStreams
.bufferWithTime(5000) //operator bufferWithTimes to catch all the event in buffer
.filter(function(arr){ //to check when the sequence is empty to notice that user is gone.
return arr.length===0;
})
.subscribe();

For more examples of how to integrate AngularJs with RXJs visit here:

https://github.com/Reactive-Extensions/RxJS/blob/master/doc/howdoi/angular.md

Differences between RxJs and Knockout

The main main difference is:
 
Reactive programming RxJs allows composing operations against asynchronous streams , like http web requests or events, and includes advanced scenarios like combining streams for example when both event A and event B occur, execute X code, but stop it if B occur again.
 
KnockoutJs is an MVVM (not MVC) framework, with it you can manage the state of yourUI with a model that maps it's functionality. This allows your to separate the logic from the view and the UI state.

 

Steve Sanderson, creator of Knockout, explained the difference on his blog:

I’m very familiar with Rx for JavaScript, having recently used it heavily on a big project, and in fact aspects of the design of Knockout are made with my Rx experiences in mind.

The key difference between Knockout’s implementation of the observer pattern and Rx’s is that Knockout automatically infers the associations and dependencies between observable from regular procedural code without you having to specify them up front though a special functional API. I wanted Knockout to use regular procedural/imperative-style code as it’s more familiar and approachable for most developers.

Another difference is that Rx is optimized for composing streams of events without state. At first I was enthusiastic about this and its functional purity, but after some time it felt increasingly like I was jumping through awkward hoops and had to invent extra ways to simulate state to manage UI commands efficiently. That’s why, in Knockout, all observables can be treated as stateful - for example you can always read their latest value (which is cached, by the way - it doesn’t recompute until the underlying data changes).

Rx goes further than Knockout into advanced ways of composing event streams, whereas Knockout goes further than Rx into UI development, letting you bind its observable to HTML DOM elements and templates and manipulate them any way you want. Rx is great at what it does but turned out not be be exactly how I wanted to build rich UIs - hence the design of Knockout.

Conclutions

I hope this article can be used as a starting point to dive into reactive programming for javascript RxJs, I encourage you to keep researching and learning about it since the intend of this post is to introduce the concept and make a comparison with other libraries like KnockoutJs, etc.