es2015 - enhance angular 1x applications

77
ES2015 ENHANCE ANGULAR 1.X APPLICATIONS Ernest Nowacki

Upload: ernest-nowacki

Post on 14-Apr-2017

393 views

Category:

Software


0 download

TRANSCRIPT

Page 1: ES2015 - enhance angular 1x applications

ES2015ENHANCE ANGULAR 1.X APPLICATIONS

Ernest Nowacki

Page 2: ES2015 - enhance angular 1x applications

AGENDAWhat?Why?How?Raw meat!

Page 3: ES2015 - enhance angular 1x applications

WHAT?ES2015 is a significant and the first update to the

language since ES5 was standardized in 2009

Page 4: ES2015 - enhance angular 1x applications

FEATURESlet + const arrows classes

enhanced object literals modules promises

template strings destructuring default + rest + spread

iterators + for..of generators subclassable built-ins

map + set + weakmap + weakset proxies symbols

math + number + string + array + object APIs binary and octal literals tail calls

unicode

Page 5: ES2015 - enhance angular 1x applications

WHY?This Ecma Standard has been adopted by the General

Assembly of June 2015.

Page 6: ES2015 - enhance angular 1x applications
Page 7: ES2015 - enhance angular 1x applications

PROSBackward compatibilityLess boilerplateBetter maintainabilityBetter preparation for Angular 2.0Easier for newcomersStaying current

Page 8: ES2015 - enhance angular 1x applications

Slide from Jafar Husain's talk: ES7 evolution of JS

Page 9: ES2015 - enhance angular 1x applications

CONSBrowser compatibilityRequire transpilationNo established best practisesNew things to learn

Page 10: ES2015 - enhance angular 1x applications

http://kangax.github.io/compat-table/es6

Page 11: ES2015 - enhance angular 1x applications

HOW?

http://babeljs.io

Page 12: ES2015 - enhance angular 1x applications

SIMPLE INTEGRATIONvar gulp = require("gulp");var babel = require("gulp­babel");

gulp.task("default", function () return gulp.src("src/app.js") .pipe(babel()) .pipe(gulp.dest("dist")););

Page 13: ES2015 - enhance angular 1x applications

ONLINE PLAYGROUND

http://babeljs.io/repl

Page 14: ES2015 - enhance angular 1x applications

WEBPACK

http://webpack.github.io

Page 15: ES2015 - enhance angular 1x applications

JUMP START WEBPACK + BABEL +ANGULAR: GULP-ANGULAR

yo gulp­angular

Page 16: ES2015 - enhance angular 1x applications

DIVE DEEP

Page 17: ES2015 - enhance angular 1x applications

LET, CONST, BLOCK SCOPElet a = 2; let a = 3; console.log( a ); // 3console.log( a ); // 2

const a = 2; console.log( a ); // 2 a = 3; // TypeError!

Page 18: ES2015 - enhance angular 1x applications

BLOCK SCOPING ES5 VS ES2015if (true) function weather() console.log( "Sun" ); else function weather() console.log( "Rain" ); weather();

Page 19: ES2015 - enhance angular 1x applications

ES5var funcs = [];for (var i = 0; i < 5; i++) funcs.push( function() console.log( i ); );funcs[3](); // 5

ES2015var funcs = [];for (let i = 0; i < 5; i++) funcs.push( function() console.log( i ); );funcs[3](); // 3

Page 20: ES2015 - enhance angular 1x applications

TEMPORAL DEAD ZONE(TDZ)

Page 21: ES2015 - enhance angular 1x applications

TEMPORAL DEAD ZONE (TDZ)console.log( a ); // undefinedconsole.log( b ); // ReferenceError!var a;let b;

if( typeof a === 'undefined' ) console.log('a is ok');

if( typeof b === 'undefined' ) //ReferenceError! console.log('b is ok');

let b;

*it's not an issue when using babel

Page 22: ES2015 - enhance angular 1x applications

(NOT SO) CONSTconst arr = ['dog', 'cat', 'snake'];arr.push('fish');console.log(arr); // ['dog', 'cat', 'snake', 'fish'];

Page 23: ES2015 - enhance angular 1x applications

EVOLUTION OF CONTROLLERS

Page 24: ES2015 - enhance angular 1x applications

BEGINING'use strict';

angular.module('app').controller('TodoCtrl', function($scope) $scope.todos = [];

$scope.newTodo = '' ;

$scope.addTodo = function(todo) $scope.todos.push(todo);

$scope.removeTodo = function (todo) $scope.todos.splice($scope.todos.indexOf(todo), 1); ;);

Page 25: ES2015 - enhance angular 1x applications

<div ng­controller="TodoCtrl"> <input type="text" ng­model="newTodo"> <button type="button" ng­click="addTodo(newTodo)"></button> <ul> <li ng­repeat="todo in todos"> todo <button type="button" ng­click="removeTodo(todo)"></button> </li> </ul></div>

Page 26: ES2015 - enhance angular 1x applications

SMALL IMPROVEMENTS(function () 'use strict'; angular.module('app').controller('TodoCtrl', TodoCtrl);

function TodoCtrl($scope) $scope.todos = []; $scope.newTodo = '' ;

$scope.addTodo = function addTodo(todo) $scope.todos.push(todo);

$scope.removeTodo = function removeTodo(todo) $scope.todos.splice($scope.todos.indexOf(todo), 1); ; );

Page 27: ES2015 - enhance angular 1x applications

controllerAs<div ng­controller="TodoCtrl as ctrl"> <input type="text" ng­model="ctrl.newTodo"> <button type="button" ng­click="ctrl.addTodo(newTodo)"></button> <ul> <li ng­repeat="todo in ctrl.todos"> todo <button type="button" ng­click="ctrl.removeTodo(todo)"></button </li> </ul></div>

Page 28: ES2015 - enhance angular 1x applications

(function () 'use strict'; angular.module('app').controller('TodoCtrl', TodoCtrl);

function TodoCtrl() this.todos = []; this.newTodo = '' ;

this.addTodo = function addTodo(todo) this.todos.push(todo);

this.removeTodo = function removeTodo(todo) this.todos.splice(this.todos.indexOf(todo), 1); ; );

Page 29: ES2015 - enhance angular 1x applications

ALMOST THERE BUT ..

Page 30: ES2015 - enhance angular 1x applications

FINAL FORM(function () 'use strict'; angular.module('app').controller('TodoCtrl', TodoCtrl);

function TodoCtrl() var vm = this; vm.todos = []; vm.newTodo = '' ;

vm.addTodo = addTodo; vm.removeTodo = removeTodo;

function addTodo(todo) vm.todos.push(todo);

function removeTodo(todo) vm.todos.splice(vm.todos.indexOf(todo), 1);

Page 31: ES2015 - enhance angular 1x applications

ES6 CLASSES'use strict';

class TodoCtrl constructor() this.todos = []; this.newTodo = '';

addTodo(todo) this.todos.push(todo);

removeTodo(todo) this.todos.splice(this.todos.indexOf(todo), 1); ;angular.module('app').controller('TodoCtrl', TodoCtrl);

Page 32: ES2015 - enhance angular 1x applications

ORLY?

Page 33: ES2015 - enhance angular 1x applications

ES5 PROTOTYPESfunction TodoCtrl() this.todos = []; this.newTodo = '';TodoCtrl.prototype.addTodo = function(todo) this.todos.push(todo);TodoCtrl.prototype.removeTodo = function(todo) this.todos.splice(this.todos.indexOf(todo), 1);;angular.module('app').controller('TodoCtrl', TodoCtrl);

Page 34: ES2015 - enhance angular 1x applications

SETTERS AND GETTERSclass MyClass constructor() this._prop = 0; get prop() console.log('getter'); return this._prop; set prop(value) console.log('setter: ' + value); this._prop = value;

let inst = new MyClass();inst = 123; // setter + 123inst.prop; // getter //123

Page 35: ES2015 - enhance angular 1x applications

EASY EXTENDINGclass Foo constructor(a,b) this.x = a; this.y = b;

gimmeXY() return this.x * this.y;

class Bar extends Foo constructor(a,b,c) super( a, b ); this.z = c;

gimmeXYZ()

Page 36: ES2015 - enhance angular 1x applications

CLASS SUMMARYMust be used with new operator, unlike ES5Foo.call(obj);It's not hoisted!Can not declare properties outside of constructor(except ES7 private proposal)Can not access super properties in constructorConstructor is optional

Page 37: ES2015 - enhance angular 1x applications
Page 38: ES2015 - enhance angular 1x applications

HANDLING DIclass Ctrl constructor(Service, AnotherService) this.Service = Service; this.AnotherService = AnotherService;

doSomething() this.Service.doSomething();

Page 39: ES2015 - enhance angular 1x applications

MY PREFERRED WAYlet internal;

class Ctrl constructor(Service, AnotherService) internal = Service, AnotherService;

doSomething() internal.Service.doSomething();

Page 40: ES2015 - enhance angular 1x applications

BE CAREFUL WITH GETTERS<span ng­repeat="n in ctrl.items100 track by $index"> e2Ctrl.test</span>

class Ctrl constructor() this.items100 = new Array(100); this._test = 'some test value';

get test() console.log('test'); return this._test;

//100x test + in digest cycles

Page 41: ES2015 - enhance angular 1x applications

COMMON LOGIC IN SERVICESclass StateAware constructor() this.state = current: 'init' ;

load() this.state.current = 'loading'; return this.loadData() .then((resp) => this.data = resp; ) .finally(() = > this.state.current = 'ready'; );

Page 42: ES2015 - enhance angular 1x applications

HOW ABOUT DIRECTIVES?

Page 43: ES2015 - enhance angular 1x applications

class Sample constructor() this.restrict = 'E'; this.scope = ; this.controller = 'SampleCtrl'; this.controllerAs = 'ctrl'; this.templateUrl = 'sample.html'; this.bindToController = info: '=' ; angular.module('app').directive('sample', () => new Sample());

Page 44: ES2015 - enhance angular 1x applications

MODULES

Page 45: ES2015 - enhance angular 1x applications

KEEPING IT SIMPLEconsole.log('This will fire on import');var globalVariable = "This looks bad";

class Ctrl something() return 'something'; angular.module('app').controller('Ctrl', Ctrl);

angular.module('app', []);import 'Ctrl';console.log(globalVariable);

//This will fire on import//undefined

Page 46: ES2015 - enhance angular 1x applications

BEING MORE SPECIFICclass Service something() return 'something'; export default Service;

import Service from './services/Service';

angular.module('app', []).service('Service', Service);

Page 47: ES2015 - enhance angular 1x applications

BEING PICKYclass Component constructor() //.. standard DDO this.controller = 'Ctrl'; this.controllerAs = 'ctrl'; this.bindToController = true; this.template = '<div>ctrl.something</div>'; class Ctrl constructor() this.something = 'Some text'; export Component, Ctrl ;

import Component, Ctrl from 'componentDirective';angular.module('app', []) .controller('Ctrl', Ctrl) .directive('component', () => new Component());

Page 48: ES2015 - enhance angular 1x applications

IMPORTING WITH ALIASexport function helperFunction() // ..export function getSomething() // ..export var randomVariable = 'o_O';

import * as lib from 'helpers';

lib.helperFunction();console.log(lib.randomVariable);

Page 49: ES2015 - enhance angular 1x applications

WHY MODULES?Standarized syntaxBetter code organizationAvoid pollution of global namespace

Page 50: ES2015 - enhance angular 1x applications
Page 51: ES2015 - enhance angular 1x applications

let data = [ id: 1, name: 'John Snow', deleted: true, id: 2, name: 'Ned Stark', deleted: true, //.. far far down .. id: 60, name: 'Aria Stark', deleted: false];

Standard functiondata.filter(function(person) return !person.deleted;);

Arrow functiondata.filter(person => !person.deleted);

Page 52: ES2015 - enhance angular 1x applications

USAGE IN CALLBACKSfunction Clickable() this.clicks = 0;

$('.elem').on('click', () => this.clicks++; console.log(this.clicks); );

Page 53: ES2015 - enhance angular 1x applications

MULTIPLE ARGUMENT CALLSdata.forEach((person, index) => console.log(`$index. $person.name`););

Page 54: ES2015 - enhance angular 1x applications

SYNTAX GOTCHAlet returnItem = id => (id: id, name: 'Some name');

Page 55: ES2015 - enhance angular 1x applications

SUMMARY1. Lexical this2. Can't change this3. Can't be used with new4. Don't have arguments array-like object

Page 56: ES2015 - enhance angular 1x applications

TEMPLATE STRINGSlet name = "Ice Cube";let greeting = `Hello $name!`;console.log(greeting); //Hello Ice Cube

var text =`This ismore then oneline!`;

console.log( text );//This is//more then one//line!

Page 57: ES2015 - enhance angular 1x applications

TAGGINGlet message = Currency`You should pay $value @currency@ discount.`;

function Currency(templateData, ...args) return templateData.map((part, index) => let str = part; if( args[index] ) str = part + String(args[index]); return str.replace('@currency@', 'PLN'); ).join('');

Page 58: ES2015 - enhance angular 1x applications

setOptions(0, 500); //500, 500, blur

DEFAULT, SPREAD, RESTES5

function setOptions(debounce, interval, event) debounce = debounce || 500; interval = interval || 100; event = event || 'blur';

console.info(debounce, interval, event);

setOptions(); //500, 100, blursetOptions(200); //200, 100, blursetOptions(undefined, null, 'change'); //500, 100, change

Page 59: ES2015 - enhance angular 1x applications

setOptions(undefined, null, 'change'); //500, 0, change

ES2015function setOptions(debounce = 500, interval = 100, event = 'blur') console.info(debounce, interval, event);

setOptions(); //500, 100, blursetOptions(200); //200, 100, blursetOptions(0, 500); //0, 500, blur

Page 60: ES2015 - enhance angular 1x applications

SPREADES5

function foo(x,y,z) console.log( x, y, z );foo.apply( null, [1,2,3] ); // 1 2 3

ES2015function foo(x,y,z) console.log( x, y, z );foo( ...[1,2,3] ); // 1 2 3

Page 61: ES2015 - enhance angular 1x applications

ANOTHER USAGE OF SPREADlet a = [2,3,4];let b = [ 1, ...a, 5 ];console.log( b ); // [1,2,3,4,5]

Page 62: ES2015 - enhance angular 1x applications

RESTfunction foo(x, y, ...z) console.log( x, y, z );foo( 1, 2, 3, 4, 5 ); // 1 2 [3,4,5]

Page 63: ES2015 - enhance angular 1x applications

ES5function test() var args = Array.prototype.slice.call( arguments ); //do sth

ES2015function test(...args) //do sth

Page 64: ES2015 - enhance angular 1x applications

DESTRUCTURING, PROPERTY ASSIGNSHORTCUTS

ES5function data() return [1, 2, 3];let tmp = data();let a = tmp[0], //a = 1 b = tmp[1], //b = 2 c = tmp[2]; //c = 3

ES2015function data() return [1, 2, 3];let [a,b,c] = data(); // a = 1, b = 2, c = 3

Page 65: ES2015 - enhance angular 1x applications

DESTRUCTURING OBJECTSfunction data() return firstName: 'John', lastName: 'Snow', occupation: 'Lord Commander of the Night's Watch' ;var firstName, lastName: a, occupation: b = data();

//firstName = 'John',//a: 'Snow',//b: 'Lord Commander of the Night's Watch'

Page 66: ES2015 - enhance angular 1x applications

UNIVERSITY CLASSIC - VARIABLE SWAPvar x = 10, y = 20;[ y, x ] = [ x, y ];console.log( x, y ); // 20 10

Page 67: ES2015 - enhance angular 1x applications

DESTRUCTURE NULL OR UNDEFINED =ERROR!

let x, y = null;let a, b = undefined;

HOWEVER UNEXISTING VARIABLESARE OK

let options = a: 1, b: 2;let a, c = options;console.log(a); // 1console.log(b); //undefinedconsole.log(c); //undefined

Page 68: ES2015 - enhance angular 1x applications

SYNTAX GOTCHAlet person = id: 1, address: street: 'Przy parku', city: 'Warszawa' ;let id;let address;

id, address = person; //Error(id, address = person); //Ok!

Page 69: ES2015 - enhance angular 1x applications

OBJECTS AND ARRAYS AREDESTRUCTURED AS REFERENCES!

let color = name: 'white', rgb: [255, 255, 255];

let name: colorName, rgb = color;console.log(colorName); //'white'console.log(rgb); //[255, 255, 255]console.log(rgb === color.rgb); // true

Page 70: ES2015 - enhance angular 1x applications

DESTRUCTURE FUNCTION PARAMS

ES5function setCookie(name, value, options) options = options || ; let secure = options.secure; let path = options.path; let domain = options.domain; //....

setCookie('presentation', 'es2015', secure: false;);

Page 71: ES2015 - enhance angular 1x applications

DESTRUCTURE FUNCTION PARAMS

ES2015function setCookie(name, value, secure, path, domain = ) //...

setCookie('presentation', 'es2015', secure: false;);

Page 72: ES2015 - enhance angular 1x applications

PROMISES

Page 73: ES2015 - enhance angular 1x applications

ES2015 PROMISE SYNTAXvar promise = new Promise((resolve, reject) => setTimeout(resolve, 1000););

Page 74: ES2015 - enhance angular 1x applications

REMOVING CALLBACK LEGACY CODEimport LegacyLib from 'LegacyLib';

let internal;class LegacyLibDecorator constructor($q) internal = $q; loadData() let deferred = $q.defer(); LegacyLib.loadData( result => deferred.resolve(result), error => deferred.reject(error) ); return deferred;

Page 75: ES2015 - enhance angular 1x applications

REFACTOR USING PROMISE SYNTAXimport LegacyLib from 'LegacyLib';

let internal;class LegacyLibDecorator constructor($q) internal = $q; loadData() return $q((resolve, reject) => LegacyLib.loadData( result => resolve(result), error => reject(error) ); );

Page 76: ES2015 - enhance angular 1x applications
Page 77: ES2015 - enhance angular 1x applications

Mozilla Hacks: ES6 in depth

ExploringJS Feature overview

Babel learn-es6 Great talk to go to next

http://hacks.mozilla.org/category/es6-in-depthhttp://exploringjs.com/es6/

http://github.com/lukehoban/es6featureshttp://babeljs.io/docs/learn-es2015/

https://www.youtube.com/watch?v=DqMFX91ToLw