Friday, December 30, 2016

JavaScript Evolution ESMAScript 6 - Promises

Typically, to avoid blocking the main thread of execution, we write non-blocking code using asynchronous style function pass callback like this:
getResult("Saas", function(result) {
  ui.renderSidebar(results);
}
When nested callbacks start to grow, our code becomes harder to read. We have to check for error on every callback.
getResultFromServer("Saas", function(error, results) {
  if (error) { // handle error };
  ui.renderSideBar(results, function(error, results) {
    if (error) { //handle error };
    sendNotificationToServer(results, function(error, response) {
      if (error) { // handle error };
      doSomethingElse (response, function(error)) {
        if (error) { //handle error };
        //...
      };
    };
  };
});
Promises brought to JavasScript trying to offer a solution to this issue by bringing new abstraction that allows us to write asynchronous code in an easier way.
getResultFromServer("Saas")
  .then(ui.renderSidebar)
  .then(sendNotificationToServer)
  .then(doSomethingElse)
  .catch(function(error) {
    console.log("Error :" + error);
  }
The Promise constructor function takes an anonymous function with 2 callback argument known as handles. Handles are responsible for resolving or rejecting the Promise.

Create a new Promise automatically set it to the pending state. Then, it can become fulfilled(resolve) or rejected(reject).

One thing to remember is that Promise not return a result, its return a future value, such as the eventual result if asynchronous operation.

Let's wrap the XMLHttpRequest object API within a Promise. Calling the resolve() handler moves the Promise to a fulfilled state. We'll call the reject() handler for unsuccessful status codes and also when the error event is triggered on our request object. Both move the Promise to a rejected state.
function getResultFromServer(pollName){
  return new Promise(function(resolve, reject) {
    request.onload = function() {
      if (request.status >= 200 && request.status < 400) {
        resolve(request.response);
      } else {
        reject(new Error(request,status));
      };
    };
    request.oneerror = function() {
      reject(new Error ("Error Fetching Results"));
    };
  };
};
We can use then() method to read results from the Promise once resolved. We can chain multiple calls to then(). The return value from 1 call is passed as an argument to the next.

Once an error occurs, execution moves immediately to the catch() function. None of the remaining then() function are invoked.
getResultFromServer("Saas")
  .then(function(result){
    // Return value to next then().
    return result.filter((result) => result.city === "Orlado");
  })
  .then(function(resultFromOrlando){
    ui.renderSideBar(resultsFromOrlando);
  })
  .catch(function(error) {
    console.log("Error : " + error);
  })

Friday, December 23, 2016

JavaScript Evolution ESMAScript 6 - Module

In this section, we learn about using Module to encapsulate classes.

To export classes, use the export syntax with the class name inside curly braces.

flash-message.js
class FlashMessage {

  constructor(message) {
    this.message = message;
  }

  renderAlert() {
    alert(`${this.message} from alert`);
  }

  renderConsole() {
    console.log(`${this.message} from log`);
  }

}

export {FlashMessage} // Export class to outside world.
To import the class, we must use the same export name.

app.js
import {FlashMessage} from './flash-message';

let flash = new FlashMessage('Hello');
flash.renderAlert(); // Alert -> Hello from alert
flash.renderConsole(); // Console -> Hello from log

JavaScript Evolution ESMAScript 6 - Classes

A common encapsulation approach in JavaScript is using construction function. Adding the prototype required a bit of coding and some repetition. We can do better using new Class syntax to write the object-oriented language.

To define a class, we use class syntax followed by the name of the class. The body of a class is the part between curly braces.

Currently, there is no access modifier in JavaScript, like private and protected in another language. Prefixing a method with an underscore is a convention for indicating that it shouldn't be invoked from public API.
class SponsorWidget {
  // Constructor method is a special method for creating and initializing an object.
  // Its run every time a new instance is created with the new operator.
  constructor(name, description, url) {
    this.name = name;
    this.description = description;
    this.url = url;
  }

  // Private method
  _buildURL(url) {
    console.log(url);
  }

  // Instance method definition in classes look just like the method initializer shorthand in object.
  render() {
    // Variable set in constructor can be accessed from all other instance method using this. syntax.
    let link = this._buildURL(this.url);
  }
}

// Here is how we involve the class
let sponsorWidget = new SponsorWidget(
  "Google",
  "Search",
  "https://www.google.com"
);

sponsorWidget.render();

One benefit of class syntax is that we can use class inheritance. The extends syntax is used to create a class that inherit methods and properties from another class. The super method runs the constructor function from the parent class.
// Parent Class
class Widget {
  constructor() {
    this.baseCSS = "site-widget";
  }

  parse(value) {
    console.log(this.baseCSS);
  }
}

// Child Class
class SponsorWidget extends Widget {
  constructor(name, description, url) {
    super(); // Run parent constructor.
    this.name = name;
    this.description = description;
    this.url = url;
  }

  _buildURL(url) {
    console.log(url);
  }

  render() {
    let link = this._buildURL(this.url);

    // Calling inherit property and method
    this.parse(this.baseCSS);
  }
}
You can override the inherited method by naming the same method name in child class.
// Parent Class
class Widget {
  constructor() {
    this.baseCSS = "site-widget";
  }

  parse(value) {
    return this.baseCSS;
  }
}

// Child Class
class SponsorWidget extends Widget {
  constructor(name, description, url) {
    super(); // Run parent constructor.
    this.name = name;
    this.description = description;
    this.url = url;
  }

  _buildURL(url) {
    console.log(url);
  }

  // Overriding inherit method
  parse(value) {
    // Using super to call parent method
    console.log("Overring method: " + super.parse(this.name));
  }

  render() {
    let link = this._buildURL(this.url);

    // Calling inherit property and method
    this.parse(this.baseCSS);
  }
}

Thursday, December 22, 2016

JavaScript Evolution ECMAScript 6 - Sets

Before we understand the needs to use Sets, let's go back to understand Array limitation.

Array in JavaScript is very simple to use, but 1 thing they don't do is Array doesn't enforce uniqueness of items. Duplicate entries are allowed.
let tags = [];
tags.push ("JavaScript");
tags.push("Programming");
tags.push("Web");
tags.push("Web");

console.log(tags.length); // Return 4
If we want to prevent duplicate entry to be added into a collection, instead of Array, we can use Set. Set object stores uniques values of any types, where primitives values or object references.
let tags = new Set();
tags.add("JavaScript");
tags.add("Programming");
tags.add({version: "2015"}); // We can add object
tags.add("Web");
tags.add("Web"); // Duplicate entry are ignored.

console.log(tags.size); // Return 4
Set object is iterative, which means they can be used with for...of and destructuring.
for (let tag of tags) {
  console.log(tag);
}

// Return:
// JavaScript
// Programming
// {version: "2015"}
// Web

let [a, b,c, d] = tags;
console.log(a ,b, c, d);

// Return JavaScript, Programming, {version: "2015"}, Web

JavaScript Evolution ECMAScript 6 - WeakMap (Better with Memory with Limitation)

WeakMap is a type of Map where only Objects can be passed as keys. Primitive data types such as String, Number, Boolean, etc are not allowed.
let user = {};
let comment = {};

let mapSettings = new WeakMap();
mapSettings.set(user, "Sam");
mapSettings.set(comment, "Great Post!!!");

console.log(mapSettings.get(user)); // Return Sam
console.log(mapSettings.get(comment)); // Return Great Post!!!
You can't assign primitive data types as key.
let mapSettings = new WeakMap();
mapSettings.set("user", "Sam"); // Return Error - Invalid value used as weak map key
Other methods available are has() and delete().
console.log(mapSettings.has(user)); // Return true
console.log(mapSettings.delete(user)); // Return true
WeakMap is not iterable, therefore they can't be used with for...of.

JavaScript Evolution ECMAScript 6 - Maps

Maps are a data structure composed of a collection of key/value pairs. they are very useful to store simple data such as property value. They are present in many programming languages such a Scala.

The key in Map must be unique and associated with only 1 value.

key ---> value
key ---> value
key ---> value

JavaScript developer explores to Map thru Object. It is possible to use Object as Map, but there is some issue with that. The biggest issue of using Object as Map is the key always converted to String.

Let's take a look at the below example:
let user1 = {name: "Sam"};
let user2 = {name: "Tyler"};

let totalReplies = {};
totalReplies [user1] = 5;
totalReplies [user2] = 42;

console.log(totalReplies [user1]); // Return 42
console.log(totalReplies [user2]); // Return 42
Although we assign 2 different value to the key, the last assign overwrites the previous value because JavaScript converts the Object to String - [object, object].

To get around this issue, we should use the Map. Any value may be used as either a key or a value are not converted to String. Let change totalReplied to a Map.
let user1 = {name: "Sam"};
let user2 = {name: "Tyler"};

let totalReplies = new Map();
totalReplies.set(user1, 5);
totalReplies.set(user2, 42);

console.log(totalReplies.get(user1)); // Return 5
console.log(totalReplies.get(user2)); // Return 42
As you can see, the 2 value assigned to different Object key as expected.

We use get() and set() methods to access the value in Map. To delete a value in Map, you can use delete() method.
totalReplies.delete(user1);
The map is iteratable, so they can be used in the for...of loop. Each ran of the loop returns a [key, value] pair for an entry in the Map.
let mapSettings = new Map();
mapSettings.set("user", "Sam");
mapSettings.set("topic", "ES2015");

for (let [key, value] of mapSettings) {
  console.log(`${key} = ${value}`);
}

// Return
// user = Sam
// topic = ES2015

JavaScript Evolution ECMAScript 6 - New Additional to Array

Assigning From Array to Local Variables

Typically we access array elements using index.
let users = ["Sam", "Tyler", "Brook"];
let a = users[0];
let b = users[1];
let c = users[2];
In ES2015, new implement in Array destructuring allows us to write less code.
let users = ["Sam", "Tyler", "Brook"];
let [a, b, c] = users;
If there is any value that not interested in, we can discard.
let users = ["Sam", "Tyler", "Brook"];
let [a, ,b] = users;
We can combine destructuring with rest parameters to group values into other Array.
let users = ["Sam", "Tyler", "Brook"];
let [first, ...rest] = users;
console.log(first); // Return "Sam".
console.log(rest); // Return a new Array ["Tyler", "Brook"]

Using for...of to loop over Array

The for...of statement iterates over property values, and it's a better way to loop over arrays and other iterate objects.

Here is the typical way we loop thru array using index.
let names = ["Sam", "Tyler", "Brook"];
for (let index in names) {
  console.log (names[index]);
}
Now, using for...of, we don't use the index.
let names = ["Sam", "Tyler", "Brook"];
for (let name of names) {
  console.log(name);
}

Finding an Element in an Array

Array find returns the first element in the Array that satisfies a provided testing function.
let users = [
  {login: "Sam", admin: false},
  {login: "Brook", admin: true},
  {login: "Tyler", admin: true}
];
let admin = users.find( (user) => {
  return user.admin;
});
console.log(admin); // Return {login: "Brook", admin: true}

Tuesday, December 20, 2016

JavaScript Evolution ECMAScript 6 - Merging Object via Object.assign()

Copying all properties of one object to another one is a common operation in JavaScript. In this article, we gonna explore ES2015 new implementation of Object.assign().

Object.assign() syntax is Object.assign(target, sources, ...). The target object is the return value and the source is the object to be copied.

Example of merging an object:
let first = {first: "Sam"};
let last = {last: "Wong"};
let person = Object.assign(first, last);
console.log(person); // Return {first: "Sam", last: "Wong"}
console.log(first); // Return {first: "Sam", last: "Wong"} as the source also changed.
Example of merging an object without modifying the source (cloning)
let first = {first: "Sam"};
let last = {last: "Wong"};
let person = Object.assign({}, first, last);
console.log(person); // Return {first: "Sam", last: "Wong"}
console.log(first); // Return {first: "Sam"} as source's value preserve
Example of merge multi-source and value is overwritten when the key is equal.
let b = Object.assign({foo:0},{foo:1},{foo:2});
console.log(b); // Return {foo:2} as last object prevail.
In use-case, Object.assign() is practical to write flexible and usable function. In the coming example, we are going to write a buildUser function which accepts 2 parameters (first, last), and a custom Options (lettercase, and targetElement) will vary according to each call of the function. The function can be called in many ways.
buildUser("Sam", "Wong");
buildUser("Sam, "Wong", {lettercase: "upper"});
buildUser("Sam", "Wong", {lettercase: "upper", targetElement: ".username"})
For such function, it is okay to accept the object parameter instead using the name parameter.

Example of Name Parameter:
// Bad implementation as not easy to read when scale to more arguments.
function buildUser(first, last, {lettercase, targetElement} = {})
Example of Object Parameter:
// Good implement as easy to read when scale.
function buildUser(first, last, options = {})
Some options might not be specified by the caller, so we need to have default values. One way we can do it by using ||. This code worked, the issue here is the default value can be anywhere which is hard to read.
function buildUser (first, last, options = {}){
  let lettercase = options.lettercase || "uppercase";
  let targetElement = options.targetElement || ".username";
  ...
}
To solve this, we group default values in 1 place. The grouping default value is the common pattern in a large project. It can help us write more idiomatic JavaScript. The next step is to merge the default and options using the Object.assign() syntax. The important point is options value must overwrite default value and the result stores in setting variable.
function buildUser(first, last, options = {}) {
  let defaults = {
    lettercase = "upper",
    targetElement = ".username"
  }

  let setting = Object.assign({}, defaults, options);
  console.log(setting.lettercase);
  console.log(setting.targetElement);
}

JavaScript Evolution ECMAScript 6 - Template String

Template String is string literals allowing embedded expressions.

Below is the typical way we assign a text into a variable.
function buildUser(first, last) {
  let fullname = first + " " + last;
  ...
}
In ES2015, we can wrap the entitled text with backtick `. Any JavaScript need to be evaluated inside the backtick, wrap it with ${...}.
function buildUser(first, last) {
  let fullname = '${first} ${last}';
  ...
}
Template String offers a new and much better way to write multiple strings.
let longText = ' Hi ${username}
This is a very
veeery
long text.

Regards,
  ${admin.fullname}
`;

// Newline characters is preserve and output to screen.
console.log(longText);

JavaScript Evolution ECMAScript 6 - Simplified Object

Removing Repetition Object

Here is the typical way we write a return object function.
function buildUser(first, last) {
  let fullname = first + " " + last;
  return {first : first, last : last, fullname : fullname};
}
The returned object with keys and variables with the same name is repetitive. We can remove duplicate variables names from object properties when those properties have the same name as the variables being assigned to them.
function buildUser(first, last) {
  let fullname = first + " " + last;
  return {first, last, fullname};
}
This simplicity called Object Initializer Shorthand.

Object Initializer Shorthand can works anywhere, as long as a new object is returned, not just from function.
let first = "Sam";
let last = "Wong";
let userOld = {first : first, last : last};
let userNew = {first, last}; // Simplified

Object Destructing 

Let's look at another side of reading properties from an object.

Here is the typical way we read properties from an object.
let user = buildUser("Sam", "Wong");
let first = user.first;
let last = user.last;
let fullname = user.fullname;
In ES2015, we can read an object's properties using simplified syntax.
let {first, last, fullname} = buildUser("Sam", "Wong");
console.log(first);
console.log(last);
console.log(fullname);
We can read as well as subset return function properties. Below example, we just want to grab the fullname and leave first, last out.
let {fullname} =  buildUser("Sam", "Wong");;
console.log(fullname);

Method Initializer Shorthand

Here is the typical way we write method in function object.
function buildUser(first, last, age) {
  let fullname = first + " " + last;
  const AGE_LIMIT = 18;
  return {
    first,
    last,
    fullname,
    isAgeOverLimit : function () {
      return age >= AGE_LIMIT;
    }
  }
}
With method initializer shorthand, we can simplify by removing the function ().
function buildUser(first, last, age) {
  let fullname = first + " " + last;
  const AGE_LIMIT = 18;
  return {
    first,
    last,
    fullname,
    // Less character and easier to read.
    isAgeOverLimit () {
      return age >= AGE_LIMIT;
    }
  }
}

Monday, December 5, 2016

JavaScript Evolution ECMAScript 6 - Function with Rest Parameter

JavaScript functions have a built-in object called the argument object. The argument object contains an array of the argument used when the function is called. This kind of function called variadic function.
x = displayTags("A","B","C");
function displayTags() {
  for (let i in arguments){
    let tag = arguments[i];
    addTagTopic(tag);
  }
}
The variadic function gives a major problem where we add an argument, its break our code.
x = displayTags("A","B","C");
function displayTags(targetElement) {   let target = findElement(targetElement);   for (let i in arguments){     let tag = arguments[i]; // Break since the last argument it is no longer a tag.     addTagTopic(tag);   } }
The new rest parameter syntax allows us to represent an indefinite number of arguments as an Array. This way, changes to function signature are less likely to break the code.
function displayTags(...tags) {
  for (let i in tags){
    let tag = tags[i];
    addTagTopic(tag);
  }
}
// Rest parameter must go last.
function displayTags(targetElement, ...tags) {
  let target = findElement(targetElement);
  for (let i in tags){
    let tag = tags[i];
    addTagTopic(tag);
  }
}

JavaScript Evolution ECMAScript 6 - Function with Default Parameter

In ES2015, a developer can add a default parameter into a function. Example:
function loadProfile(usernames=[]){
  if (usernames.lenght > 3){
    let loadingMessage ="This will take a while.";
  }
}
With default parameter, you can call the function either
loadProfile(['Simon','Alex','Arlene']);
Or
loadProfile();
Scala has more powerful default parameter. Let's create Scala function with default parameter.
def addInt(a:Int=5, b:Int=7) = {
  var sum: Int = a + b;
  return sum
}
You can call the function by passing the parameter using a pointer.
addInt(b=10)
Passing parameter using pointer is not implement in JavaScript.

JavaScript Evolution ECMAScript 6 - Using let and const

Prior executing code, JavaScript moves var declarations all the way up to the top of the scope. This is known as a hoist. Example:
function loadProfile(usernames) {
  if(usernames.lenght > 3) {
    var loadingMessage = "This will take a while";
  }
}
JavaScript runtime transform to
function loadProfile(usernames) {
  var loadingMessage;
  if(usernames.lenght > 3) {
    loadingMessage = "This will take a while";
  }
}
This explained developer can access the variable outside the block. Example:
function loadProfile(usernames){
  if(usernames.length > 3) {
    var loadingMessage = "This will take a while";
  }
  consolo.log (loadingMessage );
  // Output is unexpected - can be "This will take a while" or undefined.
}
var variable can be accessed in entitled function which might cause unexpected behaviour. One way you can avoid this by introducing a new variable declaration let.

let variables are scoped to the nested block and are Not hoisted. Block is any code section within curly braces like if, else, while, etc. Example:
function loadProfile(usernames) {
  if (usernames.length > 3) {
    let loadingMessage ="This might take a while";
  }
  consolo.log(loadingMessage);
  // Output is ReferencesError: loadingMessage is not defined.
}
Variables declared with let can be reassigned, but cannot be redeclared within the same scope.
let loadingMessage = "Hello";
loadingMessage = "Goodbye"; // Reassigning is allowed.
let loadingMessage = "Hello";
let loadingMessage = "Goodbye";
// Re declaring is not allowed.
// TypeError: Identified 'loadingMessage' has already been declared.
Second type of new variable is const. const keyword created read-only named constant. Example
const MAX_USERS = 3;
Constant cannot be reassigned. Example:
const MAX_USERS = 3;
MAX_USERS = 10; // Error
Constant must be assigned an initial value. Example:
const MAX_USERS = 3; // No error.
const MAX_USERS;
MAX_USERS = 3; // Error
Constant are scoped to the nearest block, same to let.