Reasons to use ES6 for Angular 1.5 applications

First of all the current version of JavaScript ( ES5 ) is quite old, it was released on December 3, 2009 and was used for 7 years and of course she did his job. Like everything also JavaScript should evolve so a new version was release in June 2015 with many cool features.

If you are the greatest fan of Internet Explorer you will have some problems with ES6 because is not supported right now ( 13 June 2016 ) and you need to use some tooling to convert your code from ES6 to ES5.

Actual support of ES6:

Screen Shot 2016-07-13 at 18.26.43

 

ES6 Features:

 

Variables and constants

Now you can finally use immutable data in your code with const and defined block scoped variables with let


const START_FROM = 1; //immutable constant

for(let i=START_FROM;i<10;i++)
{
...
}

//  here i is undefined

 

Arrow functions

This is a major feature added to ES6 which can be confusing at first, but has benefits in larger code bases.


// Example 1

[1,2,3,4,5].filter((n) => n < 2); // [3, 4, 5]

// Example 2

class Car {
  start() {
    // "this" is the scope of Car
    this.async( () => this._start() ); 
  }
}

 

Modules

Some projects, like Webpack, let you take advantage of modularization now. But, ES6 delivers it as part of native JavaScript in the browser for the first time.

The addition of modularization is a huge reason to start learning ES6 now, as it’ll change the way you work for good if you’re not already using modules.


// file main.js
import { strtolower } from './utils';
let lower = strtolower('ABC');

// file utils.js
export function strtolower(str) {
  return (str+'').toLowerCase();
}
export function uppercase(str) {
...
}

 

Spread

It’s very simple, but the spread operator is a hugely convenient syntax that’s being added to expand an array wherever it’s called

//  with ES5
function myFunction(x, y, z) { }
var args = [0, 1, 2];
myFunction.apply(null, args);

// with ES6
function myFunction(x, y, z) { }
var args = [0, 1, 2];
myFunction(...args);

 

For-of

Iterators are finally getting improvements, so you’re able to iterate through variables with less messing around. For-in has existed for a long time, but for-of is being added in ES6:


var list = [3, 5, 7];

list.foo = 'bar';
 
for (var key in list) {
  console.log(key); // 0, 1, 2, foo
}
 
for (var value of list) {
  console.log(value); // 3, 5, 7
}

 

Classes

ES6 classes encourage the prototype-based object oriented pattern and they bring support for inheritance, constructors, static methods and more. Classes make your code more concise and self-documenting, which is reason enough to use them.


class Animal {
  constructor(race) {
    this.race = race;
  }
}

class Cat extends Animal {
  constructor(race) {
    super(race);
  }
  say() {
    console.log(this.race + ' says "Meow!"');
  }
}

class Dog extends Animal {
  constructor(race) {
    super(race);
  }
  say() {
    console.log(this.race + ' says "Bark!"');
  }
}

var cat = new Cat('cheshire')
  , dog = new Dog('bulldog')
;

cat.say();
dog.say();

console.log(cat instanceof Cat);
console.log(cat instanceof Dog);
console.log(cat instanceof Animal);
console.log(dog instanceof Animal);

 

Why to use it in Angular 1.5

 

Easy migration to NG2

Doing your actual code with ES6 will let you move to NG2 very nice and easy.

Components:


// Angular 2

@Component({
  selector: 'xbutton',
  template: '<button>{{label}}</button>'
});
class XButton {
  constructor() {
    this.label = "Hi";
  }
}

// To match NG2 you can do like this on current version

angular.module('...')
       .component('xbutton',{
         template:'<button>{{$ctrl.label}}</button>',
         controller: XButton
       });
// Bussiness logic is the same
class XButton {
  constructor() {
    this.label = "Hi";
  }
}

Services:


// Angular 2

@Injectable()
class Jobs {
  constructor(private http:Http){}
  getJobs() {
    return new Promise<any[]>( (done, reject) => {
      http.get('/jobs').subscribe(done, reject);
    });
  }
}

// To match NG2 you can do like this on current version

angular.module('...')
       .service('Jobs', Jobs);

class Jobs {
  constructor( $http ) {
    this.http = $http;
  }

  getJobs() {
    return new Promise( (done, reject) => {
      http.get('/jobs').then((response)=>done(response.data), reject);
    });
  }
}

 

Cons

  • You need to use a transpiler
  • Code in production will not mirror exactly your source code

Overall there are only benefits of using ES6 for your Angular 1.5. Anyway the ES6 is there and sooner or later it will be the way how we develop front-end apps.

What are your pros and cons about ES6?

jQuery apear plugin

Simple jquery plugin used to trigger a function when a specific element apears on viewport, this callback is trigged one time.
This plugin is very useful when you what to preload an image when this apears on the viewport.


$('img[osrc]').apear(function(){
			$(this).load(function(){
				$(this).fadeIn();
			});
			$(this).attr('src',$(this).attr('osrc')).attr('osrc',null);
			console.log('apear item');
		});

In this example the image is printed with osrc attribute wich keeps the path to the image, when the apear plugin callback is trigged the osrc attribute is replaced with src attribute and add new event to loaded function to fade in the image.

Other way to use this is when you have multiple boxes ( widgets ) on the page and its not necessary to apply a javascript code to it before to apear in the viewport.


$('.widget-x').apear(initWidgetX);

Download plugin or try the Demo

Working with JSON RPC from javascript

JSON-RPC is lightweight remote procedure call protocol similar to XML-RPC. Its very simple and its used by alots of web applications at least json wich is very used in modern applications.

To communicate with server in a professional way, json-rpc is a good solution all you need to do is to create server side classes and pass it to an json rpc server class like Zend_Json_Server, read the documentation about how to create the server side.

For the client side you need to create a javascript class witch sends the request to the server and parse the response.

The json request for json-rpc is very simple has three properties in the json object: the method, params and request id.

{method : "Account.login", params : ["user","pass"], id : "194" }

And response contain the result of call, the error if it is, and the request id number.

{"result": "done", "error": null, "id": "194"}

The id of the request and response is used to  match the request and reponse of the current call. For example if you send a request and also add a listener for it, when the response comes call the listener with the specific id. This id is increasing at every request.

I made a simple json-rpc implementation for javscript that handle a json-rpc protocol. Sintax of using this rpc implementation is very simple, its provide a fluent call mode with two functions “call” and “done”.

Rpc.call("Account.login", "username", "password").done( onLoginResponse );

This Rpc class depends by a public json encoder/decoder class, you can find this class here. For this work you must to change the url from ajax call and changed to your url, and thats all.

var Rpc = {
		id   : 0,
		cid  : 0,
		callbacks:[],
		call : function()
		{
			var args = [];
			
			for(var i=0;i<arguments.length;i++)
				args.push(arguments[i]);
			
			var method;
			var tosend;
			this.id++;
			this.cid = this.id;
			
			if(args.length)
			{
				method = args.shift();

				var tosend = {method : method, params : args, id : this.cid };

				jQuery.ajax({
					async: true,
					contentType: 'application/json',
					type: 'POST',
					processData: false,
					dataType: 'json',
					url: '/api/js',
					cache: false,
					data: JSON.stringify(tosend),
					error: function(req,stat,err){
						Boxy.alert(err);
					},
					success: function(data){
						for(i=0;i<public.Rpc.callbacks.length;i++)
						{
							if(public.Rpc.callbacks[i])
							if(public.Rpc.callbacks[i].id == data.id)
							{
								var callback = public.Rpc.callbacks[i].callback;
								
								if(callback)
								{
									callback.apply(null, [data.result]);
									public.Rpc.callbacks.splice(i,1);
								}
							}
						}
					}
				});
			}
			
			return this;
		},
		
		done   : function(callback)
		{
			if(typeof(callback) == 'function')
			this.callbacks.push( { id : this.cid, callback : callback } );
		}
};