Promises in ES6

Promises are usually vaguely defined as “a proxy for a value that will eventually become available”. They can be used for both synchronous and asynchronous code flows, although they make asynchronous flows easier to reason about – once you’ve mastered promises, that is.
Consider as an example the upcoming fetch API. This API is a simplification of XMLHttpRequest. It aims to be super simple to use for the most basic use cases: making a GET request against a resource relative to the current page over http(s) – it also provides a comprehensive API that caters to advanced use cases as well, but that’s not our focus for now. In it’s most basic incarnation, you can make a request for GET foo like so.

fetch('foo')

The fetch('foo') statement doesn’t seem all that exciting. It makes a “fire-and-forget” GET request against foo relative to the resource we’re currently on. The fetch method returns a Promise. You can chain a .then callback that will be executed once the foo resource finishes loading.

fetch('foo').then(response => /* do something */)

For example,

fetch('foo', (err, res) => {
  if (err) {
    // handle error
  }
  // handle response
})

The callback wouldn’t be invoked until the foo resource has been fetched, so its execution remains asynchronous and non-blocking. Note that in this model you could only specify a single callback, and that callback would be responsible for all functionality derived from the response.
Few important points about Promises:

  • Follows the Promises/A+ specification, was widely implemented in the wild before ES6 was standarized (e.g bluebird)
  • Promises behave like a tree. Add branches with p.then(handler) and p.catch(handler)
  • Create new p promises with new Promise((resolve, reject) => { /* resolver */ })
    • The resolve(value) callback will fulfill the promise with the provided value
    • The reject(reason) callback will reject p with a reason error
    • You can call those methods asynchronously, blocking deeper branches of the promise tree
  • Each call to p.then and p.catch creates another promise that’s blocked on p being settled
  • Promises start out in pending state and are settled when they’re either fulfilled or rejected
  • Promises can only be settled once, and then they’re settled. Settled promises unblock deeper branches
  • You can tack as many promises as you want onto as many branches as you need
  • Each branch will execute either .then handlers or .catch handlers, never both
  • A .then callback can transform the result of the previous branch by returning a value
  • A .then callback can block on another promise by returning it
  • p.catch(fn).catch(fn) won’t do what you want — unless what you wanted is to catch errors in the error handler
  • Promise.resolve(value) creates a promise that’s fulfilled with the provided value
  • Promise.reject(reason) creates a promise that’s rejected with the provided reason
  • Promise.all(...promises) creates a promise that settles when all ...promises are fulfilled or 1 of them is rejected
  • Promise.race(...promises) creates a promise that settles as soon as 1 of ...promises is settled
  • Use Promisees — the promise visualization playground — to better understand promises

Generators in ES6

Generators are a new feature in ES6. You declare a generator function which returns generator objects g that can then be iterated using any of Array.from(g), [...g], or for value of g loops. Generator functions allow you to declare a special kind of iterator. These iterators can suspend execution while retaining their context.
Here is an example generator function. Note the * after function. That’s not a typo, that’s how you mark a generator function as a generator.

function* generator () {
  yield 'f'
  yield 'o'
  yield 'o'
}

A quick overview of Generators:

  • Generator functions are a special kind of iterator that can be declared using the function* generator () {} syntax
  • Generator functions use yield to emit an element sequence
  • Generator functions can also use yield* to delegate to another generator function — or any iterable object
  • Generator functions return a generator object that’s adheres to both the iterable and iterator protocols
    • Given g = generator(), g adheres to the iterable protocol because g[Symbol.iterator] is a method
    • Given g = generator(), g adheres to the iterator protocol because g.next is a method
    • The iterator for a generator object g is the generator itself: g[Symbol.iterator]() === g
  • Pull values using Array.from(g), [...g], for (let item of g), or just calling g.next()
  • Generator function execution is suspended, remembering the last position, in four different cases
    • A yield expression returning the next value in the sequence
    • A return statement returning the last value in the sequence
    • A throw statement halts execution in the generator entirely
    • Reaching the end of the generator function signals { done: true }
  • Once the g sequence has ended, g.next() simply returns { done: true } and has no effect
  • It’s easy to make asynchronous flows feel synchronous
    • Take user-provided generator function
    • User code is suspended while asynchronous operations take place
    • Call g.next(), unsuspending execution in user code

I highly recommend you go over Axel’s article on generators, as he put together an amazing write-up on use cases for generators just a few months ago.

Iterators in ES6

JavaScript gets two new protocols in ES6, Iterators and Iterables. In plain terms, you can think of protocols as conventions. As long as you follow a determined convention in the language, you get a side-effect. The iterable protocol allows you to define the behavior when JavaScript objects are being iterated.
The code below is an iterable object in ES6.

var foo = {
  [Symbol.iterator]: () => ({
    items: ['p', 'o', 'n', 'y', 'f', 'o', 'o'],
    next: function next () {
      return {
        done: this.items.length === 0,
        value: this.items.shift()
      }
    }
  })
}

Here is a quick snap-in of iterators:

  • Iterator and iterable protocol define how to iterate over any object, not just arrays and array-likes
  • A well-known Symbol is used to assign an iterator to any object
  • var foo = { [Symbol.iterator]: iterable}, or foo[Symbol.iterator] = iterable
  • The iterable is a method that returns an iterator object that has a next method
  • The next method returns objects with two properties, value and done
    • The value property indicates the current value in the sequence being iterated
    • The done property indicates whether there are any more items to iterate
  • Objects that have a [Symbol.iterator] value are iterable, because they subscribe to the iterable protocol
  • Some built-ins like Array, String, or arguments — and NodeList in browsers — are iterable by default in ES6
  • Iterable objects can be looped over with for..of, such as for (let el of document.querySelectorAll('a'))
  • Iterable objects can be synthesized using the spread operator, like [...document.querySelectorAll('a')]
  • You can also use Array.from(document.querySelectorAll('a')) to synthesize an iterable sequence into an array
  • Iterators are lazy, and those that produce an infinite sequence still can lead to valid programs
  • Be careful not to attempt to synthesize an infinite sequence with ... or Array.from as that will cause an infinite loop

Symbols in ES6

Symbols are a new primitive type in ES6. If you ask me, they’re an awful lot like strings. Just like with numbers and strings, symbols also come with their accompanying Symbol wrapper object.
We can create our own Symbols.

var mystery = Symbol()

Note that there was no new. The new operator even throws a TypeError when we try it on Symbol.

var oops = new Symbol()
// <- TypeError

For debugging purposes, you can describe symbols.

var mystery = Symbol('this is a descriptive description')

Symbols at quick glance:

  • A new primitive type in ES6
  • You can create your own symbols using var symbol = Symbol()
  • You can add a description for debugging purposes, like Symbol('ponyfoo')
  • Symbols are immutable and unique. Symbol(), Symbol(), Symbol('foo') and Symbol('foo') are all different
  • Symbols are of type symbol, thus: typeof Symbol() === 'symbol'
  • You can also create global symbols with Symbol.for(key)
    • If a symbol with the provided key already existed, you get that one back
    • Otherwise, a new symbol is created, using key as its description as well
    • Symbol.keyFor(symbol) is the inverse function, taking a symbol and returning its key
    • Global symbols are as global as it gets, or cross-realm. Single registry used to look up these symbols across the runtime
      • window context
      • eval context
      • <iframe> context, Symbol.for('foo') === iframe.contentWindow.Symbol.for('foo')
  • There’s also “well-known” symbols
    • Not on the global registry, accessible through Symbol[name], e.g: Symbol.iterator
    • Cross-realm, meaning Symbol.iterator === iframe.contentWindow.Symbol.iterator
    • Used by specification to define protocols, such as the iterable protocol over Symbol.iterator
    • They’re not actually well-known — in colloquial terms
  • Iterating over symbol properties is hard, but not impossible and definitely not private
    • Symbols are hidden to all pre-ES6 “reflection” methods
    • Symbols are accessible through Object.getOwnPropertySymbols
    • You won’t stumble upon them but you will find them if actively looking

Arrow Functions in ES6

Arrow functions are available to many other modern languages and was one of the features I sorely missed a few years ago when I moved from C# to JavaScript. Fortunately, they’re now part of ES6 and thus available to us in JavaScript. The syntax is quite expressive. We already had anonymous functions, but sometimes it’s nice to have a terse alternative.
Here’s how the syntax looks like if we have a single argument and just want to return the results for an expression.

[1, 2, 3].map(num => num * 2)
// <- [2, 4, 6]

The ES5 equivalent would be as below.

[1, 2, 3].map(function (num) { return num * 2 })
// <- [2, 4, 6]

If we need to declare more arguments (or no arguments), we’ll have to use parenthesis.

[1, 2, 3, 4].map((num, index) => num * 2 + index)
// <- [2, 5, 8, 11]

A cool aspect of arrow functions in ES6 is that they’re bound to their lexical scope. That means that you can say goodbye to var self = this and similar hacks – such as using .bind(this) to preserve the context from within deeply nested methods.

function Timer () {
    this.seconds = 0
    setInterval(() => this.seconds++, 1000)
}
var timer = new Timer()
setTimeout(() => console.log(timer.seconds), 3100)
// <- 3
  • Terse way to declare a function like param => returnValue
  • Useful when doing functional stuff like [1, 2].map(x => x * 2)
  • Several flavors are available, might take you some getting used to
    • p1 => expr is okay for a single parameter
    • p1 => expr has an implicit return statement for the provided expr expression
    • To return an object implicitly, wrap it in parenthesis () => ({ foo: 'bar' }) or you’ll get an error
    • Parenthesis are demanded when you have zero, two, or more parameters, () => expr or (p1, p2) => expr
    • Brackets in the right-hand side represent a code block that can have multiple statements, () => {}
    • When using a code block, there’s no implicit return, you’ll have to provide it — () => { return 'foo' }
  • You can’t name arrow functions statically, but runtimes are now much better at inferring names for most methods
  • Arrow functions are bound to their lexical scope
    • this is the same this context as in the parent scope
    • this can’t be modified with .call, .apply, or similar “reflection”-type methods
    • arguments is also lexically scoped to the nearest normal function; use (...args) for local arguments
  • Read ES6 Arrow Functions in Depth

Numeric Column Sorting in jqGrid

When we set the Sort Column and Sort Direction in a jqGrid, it considers the column as text by default. Even when you are sorting with numeric columns, it sorts as text.
For example – The rows on the left side will be sorted as right

1                                                      1
2                                                     100
3                                                     101
100                                                 102
101                       =>                      2
102                                                 201
201                                                 202
202                                                203
203                                                3

This happens as jqGrid considers them as text columns. For solving this problem, we can use Custom Sorting. In your colModel, specify the sorttype and use this function.

colModel: [
  { name:'rowId', index:'rowId',
    sorttype: function(cell,rowObject) {
        if (typeof cell === "string" && /^test(\d)+$/i.test(cell)) {
             return parseInt(cell.substring(4),10);
        } else {
             return cell;
        }
    }
  }
]

Resetting sorting in ng-grid

Applying sorting to an ng-grid is like a cake walk in Angular JS. But it is little tricky if you want to show the ng-grid with default data (the order in which it loaded first). Here is a solution for it.
Here I am taking a dropdown to change the sort order of the grid. So, I will be using ng-change of the dropdown to update the sort order in ng-grid.

<select ng-change="changeSortOrder" ng-model="empSortCol">
<option>Default Order</option>
<option>Name</option>
<option>Age</option>
<option>Division</option>
</select>
<div ng-grid="myGrid"></div>

Here is the changeSortOrder function.

$scope.changeSortOrder = function() {
      if($scope.empSortCol == 'Default Order') {
           // reset sortInfo
           $scope.myGrid.ngGrid.config.sortInfo = { columns:[], fields: [''], directions: []};
      }
      else {
           $scope.myGrid.sortBy($scope.empSortCol);
      }
}

 
If you are using external sorting, you can do it by clearing the lastSortedColumns.

angular.forEach($scope.myGrid.ngGrid.lastSortedColumns, function (c) {
      c.sortPriority = null;
      c.sortDirection = "";
  });
  $scope.myGrid.ngGrid.lastSortedColumns = [];

Permissions API for Web

Permissions API in Web - PranavOn.Net
Till now, when you land on a site that needs your location, Chrome immediately pops up a little request at the top of the browser window, even though you may not even really know what the site is all about. Now, as a developer, if you’ve worked with the Geolocation API before, chances are you’ve wanted to check if you had permission to use Geolocation without causing a prompt. This simply wasn’t possible. You had to request the current position and this would indicate the permission state or cause a prompt to be shown to the user. Similarly for Notifications, you need to check whether notifications are enabled or not. Each API has different (or its own) way of checking if that feature is available/enabled or not. With the increased and growing number of such APIs in there is a necessity for common way of doing this. Chrome is first one to implement this feature called ‘Permissions API’ in its 43 version which is rolled out a couple of days back.
To brief, Permissions API lets developers query and observe changes to their permission status for Geolocation, Push, Notifications, and Web MIDI. Asking for permission in context means fewer unnecessary and untimely prompts for the user.
Before the Permissions API, websites could not determine the permission state of APIs. Sites would thus attempt to use APIs immediately after page load without pre-existing permission, causing users to see confusing permission prompts without an explanation.
You can check the status of a permission using the permissions.query() method. This will return a status of granted (you have permission), denied (you are blocked from accessing the API) or prompt (user needs to be prompted).

// Checking for Geolocation API Permissions  
navigator.permissions.query({name:'geolocation'}).then(function(permissionStatus)
{
  console.log('geolocation permission status is ', permissionStatus.status);
  permissionStatus.onchange = function() {
    console.log('geolocation permission status has changed to ', this.status);
  };
});

For more details on Usage, have a look at Documentation or for a quick glance.
Demo: Permissions API Demo
Resources: