SlideShare a Scribd company logo
1 of 90
Download to read offline
HOW ANGULAR2 CAN
IMPROVE YOUR
ANGULARJS APPS
TODAY!
Nir Kaufman
NIR KUFMN
Nir Kaufman
- Doing Angular for years
- Wrote a book about Angular2
- Play the electric Bass
Head of Angular Development @ 500Tech
*This picture have been retouched
the actual speaker may look different
ARE YOU
READY FOR
MIGRATION?
UNAGENDA
I AM NOT GOING TO TALK ABOUT
- TypeScript
- Angular2 upgrade module
- Ng-forward library
- Data flow (Redux, RxJs)
- Angular 1.5 new Component API
BE REALISTIC.
GET READY FOR
THE MIGRATION
BUT…
DON’T FORCE
ANGULAR1 TO
BEHAVE LIKE
ANGULAR2
IT WON’T WORK.
WHAT SHOULD
YOU DO?
APPLY SOME
ANGULAR2 IDEAS
IT WILL IMPROVE
YOUR APP DESIGN
AND GET YOU
READY FOR THE
FUTURE
WINWIN SITUATION
I WILL TALK ABOUT
- Embracing Modules
- Using Classes
- Decoupling from Framework API
- Components as UI building blocks
WAIT A SECOND…
THESE ARE NOT
ANGULAR2 IDEAS!
THAT’S TRUE.
THESE ARE GOOD
PRACTICES
THAT YOU CAN
COMPLETE IN
ONE SPRINT
https://github.com/nirkaufman/ng1-coffee-shop
GRAB THE CODE
http://tinyurl.com/hdmqrem
REVIEW THE APP
EVERYTHING
IS A MODULE
$ git checkout 01_modules
USE A MODULE LOADER
Integrate a module bundler and an ES6
compiler to use javaScript modules.
http://webpack.github.io/
MODULE LOADER
module.exports = {

entry: 'index.js',



// configure loaders

module: {

loaders: [

{

test: /.js$/,

exclude: /node_modules/,

loader: "babel",

query: {presets: ['es2015', 'stage-1']}

},



// load css as inline styles

{test: /.css$/, loader: "style!css"}

]

}

};
new webpack.config.js
<script src="bundle.js"></script>
old index.html
<!-- load core scripts -->

<script src="../node_modules/angular/angular.js"></script>

<script src="../node_modules/angular-ui-router/release/angular-ui-
router.js"></script>

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



<!-- load services -->

<script src="services/logger.factory.js"></script>

<script src="services/storage.service.js"></script>

<script src="services/orders.service.js"></script>



<!-- load filters -->

<script src="filters/paid-orders.filter.js"></script>



<!-- load directives -->

<script src="directives/simple-table/simple-table.js"></script>



<!-- load controllers -->

<script src="states/home.controller.js"></script>

<script src="states/log.controller.js"></script>
<body>
<script src=“bundle.js"></script>
</body>
new index.html
import 'angular';

import 'angular-ui-router';

import './assets/index.css';





import services from './services/services.module';

import filters from './filters/filters.module'

import directives from './directives/directives.module';

import states from './states/state.module';
new index.js
BUNDLE != CONTACT
old log.controller.js
(function (angular) {



angular.module('app')

.controller('LogController', function ($scope, $window, Orders, Storage) {

$scope.orders = Orders.getOrders();



$scope.clearHistory = function () {



if ($scope.orders.length === 0) {

return;

}



var result = $window.confirm("Clear History?");

if (result) {

Storage.clear();

$scope.orders = [];

}

}

})



}(window.angular));
new log.controller.js
export function LogController ($scope, $window, Orders, Storage) {



$scope.orders = Orders.getOrders();



$scope.clearHistory = function () {



if ($scope.orders.length === 0) {

return;

}



var result = $window.confirm("Clear History?");

if (result) {

Storage.clear();

$scope.orders = [];

}

}

}
MODULAR APPROACH
old storage.service.js
(function (angular) {


angular.module('app')

.service('Storage', function () {



var ORDERS_KEY = "ORDERS";

this.store = localStorage;



this.getOrders = function () {

return JSON.parse(this.store.getItem(ORDERS_KEY)) || [];

};



this.saveOrders = function (orders) {

this.store.setItem(ORDERS_KEY, JSON.stringify(orders))

};



this.clear = function () {

this.store.clear();

}

})


}(window.angular));
new storage.service.js
export function Storage () {



var ORDERS_KEY = "ORDERS";

this.store = localStorage;



this.getOrders = function () {

return JSON.parse(this.store.getItem(ORDERS_KEY)) || [];

};



this.saveOrders = function (orders) {

this.store.setItem(ORDERS_KEY, JSON.stringify(orders))

};

}
import {Storage} from './storage.service';



export default angular.module('services', [])

.service('Storage', Storage)
new service.module.js
old index.js
(function (angular) {



angular.module('app', ['ui.router'])

.config(function ($stateProvider, $urlRouterProvider) {



$urlRouterProvider.otherwise("/");



$stateProvider

.state('home', {

url: '/',

templateUrl: 'templates/home.html',

controller: 'HomeController'

})

.state('log', {

url: '/log',

templateUrl: 'templates/log.html',

controller: 'LogController'

})

});


}(window.angular)
new index.js
import 'angular';

import 'angular-ui-router';

import ‘./assets/index.css';


import services from './services/services.module';

import filters from './filters/filters.module'

import directives from './directives/directives.module';

import states from './states/state.module';

import {routes} from './config/routes';



angular.module('app', [

'ui.router',

services.name,

directives.name,

filters.name,

states.name
]).config(routes);



// bootstrap angular

angular.element(document).ready(function () {

angular.bootstrap(document, ['app']);

});
new routes.js
export function routes($stateProvider, $urlRouterProvider) {



$urlRouterProvider.otherwise("/");



// configure application routes

$stateProvider

.state('home', {

url: '/',

templateUrl: 'templates/home.html',

controller: 'HomeController'

})



.state('log', {

url: '/log',

templateUrl: 'templates/log.html',

controller: 'LogController'

})

}
EVERYTHING
IS A CLASS
$ git checkout 02_classes
MOVE FORWARD TO ES6
You can adopt the new syntax slowly. Start
by using classes instead of functions.
http://babeljs.io/
PLAIN SERVICES
old storage.service.js
export function Storage () {



var ORDERS_KEY = "ORDERS";

this.store = localStorage;



this.getOrders = function () {

return JSON.parse(this.store.getItem(ORDERS_KEY)) || [];

};



this.saveOrders = function (orders) {

this.store.setItem(ORDERS_KEY, JSON.stringify(orders))

};

}
new storage.service.js
export class Storage {



constructor() {

this.ORDERS_KEY = "ORDERS";

this.store = localStorage;

}



getOrders() {

return JSON.parse(this.store.getItem(this.ORDERS_KEY)) || [];

};



saveOrders(orders) {

this.store.setItem(this.ORDERS_KEY, JSON.stringify(orders))

};

}
ANGULAR FILTERS
old paid-orders.filter.js
export function paidOrders() {


return function (orders) {

return orders.filter(order => order.paid === false)

}


}
import {paidOrders} from './paid-orders.filter';



export default angular.module('filters', [])

.filter('paidOrders',paidOrders);
old filters.module.js
new paid-orders.filter.js
export class PaidOrders {



static transform () {

return (orders) => orders.filter(order => order.paid === false)

}

}
import {PaidOrders} from './paid-orders.filter';



export default angular.module('filters', [])

.filter('paidOrders', PaidOrders.transform);
new filters.module.js
VIEW CONTROLLERS
old log.controller.js
export function LogController ($scope, $window, Orders, Storage) {



$scope.orders = Orders.getOrders();



$scope.clearHistory = function () {



if ($scope.orders.length === 0) {

return;

}



var result = $window.confirm("Clear History?");

if (result) {

Storage.clear();

$scope.orders = [];

}

}

}
new log.controller.js
export class LogController {



constructor($scope, $window, Orders, Storage) {

$scope.orders = Orders.getOrders();



$scope.clearHistory = function () {



if ($scope.orders.length === 0) {

return;

}



const result = $window.confirm("Clear History?");



if (result) {

Storage.clear();

$scope.orders = [];

}

}

}

}
DROP THE
$SCOPE
MORE JAVASCRIPT LESS ANGULAR
Bind to the controller instance, use setters
for watching changes, free yourself from
$scope events
CLASS SYNTAX
$ git checkout 03_drop_the_scope
old log.controller.js
export class LogController {



constructor($scope, $window, Orders, Storage) {

$scope.orders = Orders.getOrders();



$scope.clearHistory = function () {



if ($scope.orders.length === 0) {

return;

}



const result = $window.confirm("Clear History?");



if (result) {

Storage.clear();

$scope.orders = [];

}

}

}
old routes.js
export function routes($stateProvider, $urlRouterProvider) {



$urlRouterProvider.otherwise("/");



$stateProvider

.state('log', {

url: '/log',

templateUrl: 'templates/log.html',

controller: 'LogController'

})

}
<div class="container-fluid">

<div class="row">

<div class="container-fluid">

<span ng-click="clearHistory()"><i>clear history</i></span>

<br/>

<simple-table orders="orders"></simple-table>

</div>

</div>

</div>
old log.html
new log.controller.js
export class LogController {



constructor( $window, Orders, Storage) {

this.window = $window;

this.store = Storage;

this.orders = Orders.getOrders();

}



clearHistory = function () {



if (this.orders.length === 0) {

return;

}



const result = this.window.confirm("Clear History?");



if (result) {

this.store.clear();

this.orders = [];

}

}

}
new routes.js
export function routes($stateProvider, $urlRouterProvider) {



$urlRouterProvider.otherwise("/");



$stateProvider

.state('log', {

url: '/log',

templateUrl: 'templates/log.html',

controller: ‘LogController as Logs'

})

}
<div class="container-fluid">

<div class="row">

<div class="container-fluid">

<span ng-click="Logs.clearHistory()"><i>clear history</i></span>

<br/>

<simple-table orders="Logs.orders"></simple-table>

</div>

</div>

</div>
new log.html
WATCH CHANGES
$ git checkout 04_watch_for_changes
SHALLOW WATCH?
JUST USE SETTERS.
$ git checkout 05_getters_setters
old home.controller.js
export class HomeController {



constructor(Orders, $scope) {

this.Orders = Orders;

this.menu = this.Orders.getMenuItems();

this.orders = this.Orders.getOrders();

this.selectedOrder = null;



$scope.$watch(()=>this.selectedOrder, this.changeHandler)

}



changeHandler(newVal,oldVal){

console.log('New order Was selected!');

console.log(newVal, oldVal);

}

}
new home.controller.js
export class HomeController {



constructor(Orders) {

this.Orders = Orders;

this.menu = this.Orders.getMenuItems();

this.orders = this.Orders.getOrders();

this._selectedOrder = null;

}



set selectedOrder(order){
this.changeHandler(order);

this._selectedOrder = order; 

}



changeHandler(newVal){

console.log('New order Was selected!');

console.log(newVal);

}

}
DEEP WATCHING?
THINK IMMUTABLE.
$ git checkout 06_be_immutable
old home.controller.js
export class HomeController {



constructor(Orders) {

this.Orders = Orders;

this.menu = this.Orders.getMenuItems();

this.orders = this.Orders.getOrders();

this.selectedOrder = null;

}



createOrder(clientName) {

const order = this.Orders.createOrder(clientName);

this.clientName = '';

this.selectOrder(order);

};
}
new home.controller.js
export class HomeController {



constructor(Orders) {

this.Orders = Orders;

this.menu = this.Orders.getMenuItems();

this._orders = this.Orders.getOrders();

this.selectedOrder = null;

}



set orders(orders) {

console.log('orders changed!', orders);

this._orders = orders;

}



createOrder(clientName) {

const order = this.Orders.createOrder(clientName);

this.orders = this.Orders.getOrders();

this.clientName = '';

this.selectOrder(order);

};
}
EMITTING EVENTS
$ git checkout 07_event_emitter
new dispatcher.js
export class Dispatcher {



constructor() {

this.subjects = {};

}



emit(event, payload){

this.validate(event);

this.subjects[event].forEach( callback => callback.apply(null, payload))

}



on(event, callback){

this.validate(event);

this.subjects[event].push(callback);

}



validate(event){

if(!this.subjects[event]) {

this.subjects[event] = [];

}

}

}
new storage.service.js
export class Storage {



constructor(Dispatcher) {

this.ORDERS_KEY = "ORDERS";

this.store = localStorage;

this.dispatcher = Dispatcher;

}



getOrders() {

return JSON.parse(this.store.getItem(this.ORDERS_KEY)) || [];

};



saveOrders(orders) {

this.store.setItem(this.ORDERS_KEY, JSON.stringify(orders))

this.dispatcher.emit('ORDERS_SAVED', orders);

};



clear() {

this.store.clear();

}

}
new logger.factory.js
export class Logger {



constructor($log, Dispatcher) {

this.$log = $log;

this.timeStamp = new Date().toString();



Dispatcher.on('ORDERS_SAVED', function (data) {

this.debug(`storage saved the orders!`);

console.log(data);

})

}



debug(msg) {

this.$log.debug(this.timeStamp + ": " + msg)

}



log(msg) {

this.$log.log(msg)

}

}
BREAK IT TO
COMPONENTS
COMPOSE COMPONENTS
Break the UI layer into small, maintainable
and reusable building blocks.
HOME
ORDERS LIST ORDER EDITOR
NEW ORDER
FORM
ORDER LIST
ORDER
FORM
NO ORDER
EDIT ORDER
FORM
ORDER ITEM
LIST
EDITOR
FOOTER
PROJECT SRTUCTURE
$ git checkout 08_group_by_feature
old structure new structure
new home.module.js
import {HomeController} from './home.controller';



function routes($stateProvider) {

$stateProvider

.state('home', {

url: '/',

templateUrl: 'home/home.html',

controller: 'HomeController as Home'

})

}



export default angular.module('home', [])

.config(routes)

.controller({HomeController});

DIRECTIVES AS
COMPONENTS
$ git checkout 09_directives_as_components
new folder structure
new home.module.js
function routes($stateProvider) {

$stateProvider

.state('home', {

url: '/',

template: '<home></home>'

})

}



export default angular.module('home', [])

.config(routes)

.filter('paidOrders', PaidOrders.transform)

.directive({

home,

newOrderForm,

orderList,

ordersList,

noSelectedOrder,

editOrderForm,

orderItemList,

orderEditorFooter,

orderEditor

});
new home.js
export function home () {

return {

template: `

<div class="container-fluid">

<div class="row">

<orders-list></orders-list>

<order-editor></order-editor>

</div>

</div>

`,

controller: HomeController,

controllerAs: 'Home'

}

}
new order-list.js
export function ordersList() {

return {

template: `

<div class="col-sm-6">

<new-order-form></new-order-form>

<br/>

<order-list></order-list>

</div>

`

}

}

new order-editor.js
export function orderEditor() {

return {

template: `

<div class="col-sm-6">



<no-selected-order></no-selected-order>



<div class="card" ng-if="Home.selectedOrder">

<div class="card-block">

<edit-order-form></edit-order-form>

<order-item-list></order-item-list>

<order-editor-footer></order-editor-footer>

</div>

</div>

</div>

`

}

}
new no-selected-order.js
export function noSelectedOrder () {

return {

template: `

<div class="card" ng-if="!Home.selectedOrder">

<div class="card-block">

<h4 class="card-title">No order selected.</h4>

</div>

</div>

`

}

}
new order-list-item.js
export function orderItemList () {

return {

template:`

<ul class="list-group list-group-flush">

<li class="list-group-item"

ng-repeat="menuItem in Home.selectedOrder.items">

<span class="label label-default label-pill pull-xs-right">

{{menuItem.itemPrice}}</span>

{{menuItem.itemName}}

</li>

</ul>

`

}

}
FINAL WORDS
MODULAR AND
CLEAN CODE IS
ALWAYS BETTER
MIGRATION
WON’T BE EASY
START WITH
SMALL
IMPORTANT
IMPROVEMENTS
THAT YOU CAN
APPLY TODAY
https://github.com/nirkaufman/ng1-coffee-shop
GRAB THE CODE
http://tinyurl.com/hdmqrem
THANKS
ROME 18-19 MARCH 2016
Nir@500tech.com

@nirkaufman on twitter
slideshare.net/nirkaufman/
github.com/nirkaufman
All pictures belong
to their respective authors

More Related Content

What's hot

Evan Schultz - Angular Summit - 2016
Evan Schultz - Angular Summit - 2016Evan Schultz - Angular Summit - 2016
Evan Schultz - Angular Summit - 2016Evan Schultz
 
Workshop 13: AngularJS Parte II
Workshop 13: AngularJS Parte IIWorkshop 13: AngularJS Parte II
Workshop 13: AngularJS Parte IIVisual Engineering
 
AngularJS for Java Developers
AngularJS for Java DevelopersAngularJS for Java Developers
AngularJS for Java DevelopersLoc Nguyen
 
AngularJS - Services
AngularJS - ServicesAngularJS - Services
AngularJS - ServicesNir Kaufman
 
Workshop 20: ReactJS Part II Flux Pattern & Redux
Workshop 20: ReactJS Part II Flux Pattern & ReduxWorkshop 20: ReactJS Part II Flux Pattern & Redux
Workshop 20: ReactJS Part II Flux Pattern & ReduxVisual Engineering
 
Modern Web Developement
Modern Web DevelopementModern Web Developement
Modern Web Developementpeychevi
 
Workshop 22: React-Redux Middleware
Workshop 22: React-Redux MiddlewareWorkshop 22: React-Redux Middleware
Workshop 22: React-Redux MiddlewareVisual Engineering
 
Creating a WYSIWYG Editor with React
Creating a WYSIWYG Editor with ReactCreating a WYSIWYG Editor with React
Creating a WYSIWYG Editor with Reactpeychevi
 
Angular js 2.0, ng poznań 20.11
Angular js 2.0, ng poznań 20.11Angular js 2.0, ng poznań 20.11
Angular js 2.0, ng poznań 20.11Kamil Augustynowicz
 
Building scalable applications with angular js
Building scalable applications with angular jsBuilding scalable applications with angular js
Building scalable applications with angular jsAndrew Alpert
 
Workshop 19: ReactJS Introduction
Workshop 19: ReactJS IntroductionWorkshop 19: ReactJS Introduction
Workshop 19: ReactJS IntroductionVisual Engineering
 
Using React, Redux and Saga with Lottoland APIs
Using React, Redux and Saga with Lottoland APIsUsing React, Redux and Saga with Lottoland APIs
Using React, Redux and Saga with Lottoland APIsMihail Gaberov
 
Angular js 2
Angular js 2Angular js 2
Angular js 2Ran Wahle
 
ReactJs presentation
ReactJs presentationReactJs presentation
ReactJs presentationnishasowdri
 
Intro to Redux | DreamLab Academy #3
Intro to Redux | DreamLab Academy #3 Intro to Redux | DreamLab Academy #3
Intro to Redux | DreamLab Academy #3 DreamLab
 
Angular Weekend
Angular WeekendAngular Weekend
Angular WeekendTroy Miles
 
Migrating an application from Angular 1 to Angular 2
Migrating an application from Angular 1 to Angular 2 Migrating an application from Angular 1 to Angular 2
Migrating an application from Angular 1 to Angular 2 Ross Dederer
 

What's hot (20)

Evan Schultz - Angular Summit - 2016
Evan Schultz - Angular Summit - 2016Evan Schultz - Angular Summit - 2016
Evan Schultz - Angular Summit - 2016
 
Workshop 13: AngularJS Parte II
Workshop 13: AngularJS Parte IIWorkshop 13: AngularJS Parte II
Workshop 13: AngularJS Parte II
 
AngularJS for Java Developers
AngularJS for Java DevelopersAngularJS for Java Developers
AngularJS for Java Developers
 
AngularJS - Services
AngularJS - ServicesAngularJS - Services
AngularJS - Services
 
Workshop 20: ReactJS Part II Flux Pattern & Redux
Workshop 20: ReactJS Part II Flux Pattern & ReduxWorkshop 20: ReactJS Part II Flux Pattern & Redux
Workshop 20: ReactJS Part II Flux Pattern & Redux
 
Modern Web Developement
Modern Web DevelopementModern Web Developement
Modern Web Developement
 
Workshop 22: React-Redux Middleware
Workshop 22: React-Redux MiddlewareWorkshop 22: React-Redux Middleware
Workshop 22: React-Redux Middleware
 
Creating a WYSIWYG Editor with React
Creating a WYSIWYG Editor with ReactCreating a WYSIWYG Editor with React
Creating a WYSIWYG Editor with React
 
Angular js 2.0, ng poznań 20.11
Angular js 2.0, ng poznań 20.11Angular js 2.0, ng poznań 20.11
Angular js 2.0, ng poznań 20.11
 
Angular 2.0 - What to expect
Angular 2.0 - What to expectAngular 2.0 - What to expect
Angular 2.0 - What to expect
 
Building scalable applications with angular js
Building scalable applications with angular jsBuilding scalable applications with angular js
Building scalable applications with angular js
 
Workshop 19: ReactJS Introduction
Workshop 19: ReactJS IntroductionWorkshop 19: ReactJS Introduction
Workshop 19: ReactJS Introduction
 
Using React, Redux and Saga with Lottoland APIs
Using React, Redux and Saga with Lottoland APIsUsing React, Redux and Saga with Lottoland APIs
Using React, Redux and Saga with Lottoland APIs
 
Angular js 2
Angular js 2Angular js 2
Angular js 2
 
Angular2 for Beginners
Angular2 for BeginnersAngular2 for Beginners
Angular2 for Beginners
 
ReactJs presentation
ReactJs presentationReactJs presentation
ReactJs presentation
 
Intro to Redux | DreamLab Academy #3
Intro to Redux | DreamLab Academy #3 Intro to Redux | DreamLab Academy #3
Intro to Redux | DreamLab Academy #3
 
React lecture
React lectureReact lecture
React lecture
 
Angular Weekend
Angular WeekendAngular Weekend
Angular Weekend
 
Migrating an application from Angular 1 to Angular 2
Migrating an application from Angular 1 to Angular 2 Migrating an application from Angular 1 to Angular 2
Migrating an application from Angular 1 to Angular 2
 

Viewers also liked

Angular2 - getting-ready
Angular2 - getting-ready Angular2 - getting-ready
Angular2 - getting-ready Nir Kaufman
 
Angular2 workshop
Angular2 workshopAngular2 workshop
Angular2 workshopNir Kaufman
 
Angular Pipes Workshop
Angular Pipes WorkshopAngular Pipes Workshop
Angular Pipes WorkshopNir Kaufman
 
Getting Started with Angular 2
Getting Started with Angular 2Getting Started with Angular 2
Getting Started with Angular 2FITC
 
Angularjs - Unit testing introduction
Angularjs - Unit testing introductionAngularjs - Unit testing introduction
Angularjs - Unit testing introductionNir Kaufman
 
Angular 2 overview
Angular 2 overviewAngular 2 overview
Angular 2 overviewJesse Warden
 
Angular 2 - Core Concepts
Angular 2 - Core ConceptsAngular 2 - Core Concepts
Angular 2 - Core ConceptsFabio Biondi
 
Introduction to Angular 2
Introduction to Angular 2Introduction to Angular 2
Introduction to Angular 2Knoldus Inc.
 
Building Universal Applications with Angular 2
Building Universal Applications with Angular 2Building Universal Applications with Angular 2
Building Universal Applications with Angular 2Minko Gechev
 
Data Structures in javaScript 2015
Data Structures in javaScript 2015Data Structures in javaScript 2015
Data Structures in javaScript 2015Nir Kaufman
 
redux and angular - up and running
redux and angular - up and runningredux and angular - up and running
redux and angular - up and runningNir Kaufman
 
Up & running with ECMAScript6
Up & running with ECMAScript6Up & running with ECMAScript6
Up & running with ECMAScript6Nir Kaufman
 
Adventures with Angular 2
Adventures with Angular 2Adventures with Angular 2
Adventures with Angular 2Dragos Ionita
 
Angularjs - lazy loading techniques
Angularjs - lazy loading techniques Angularjs - lazy loading techniques
Angularjs - lazy loading techniques Nir Kaufman
 
Webpack and angularjs
Webpack and angularjsWebpack and angularjs
Webpack and angularjsNir Kaufman
 

Viewers also liked (20)

Angular2 - getting-ready
Angular2 - getting-ready Angular2 - getting-ready
Angular2 - getting-ready
 
Angular2 workshop
Angular2 workshopAngular2 workshop
Angular2 workshop
 
Angular Pipes Workshop
Angular Pipes WorkshopAngular Pipes Workshop
Angular Pipes Workshop
 
Getting Started with Angular 2
Getting Started with Angular 2Getting Started with Angular 2
Getting Started with Angular 2
 
Solid angular
Solid angularSolid angular
Solid angular
 
Angularjs - Unit testing introduction
Angularjs - Unit testing introductionAngularjs - Unit testing introduction
Angularjs - Unit testing introduction
 
Angular 2 overview
Angular 2 overviewAngular 2 overview
Angular 2 overview
 
Angular 2 - Better or worse
Angular 2 - Better or worseAngular 2 - Better or worse
Angular 2 - Better or worse
 
Angular 2 - Core Concepts
Angular 2 - Core ConceptsAngular 2 - Core Concepts
Angular 2 - Core Concepts
 
Introduction to Angular 2
Introduction to Angular 2Introduction to Angular 2
Introduction to Angular 2
 
Building Universal Applications with Angular 2
Building Universal Applications with Angular 2Building Universal Applications with Angular 2
Building Universal Applications with Angular 2
 
Data Structures in javaScript 2015
Data Structures in javaScript 2015Data Structures in javaScript 2015
Data Structures in javaScript 2015
 
redux and angular - up and running
redux and angular - up and runningredux and angular - up and running
redux and angular - up and running
 
Up & running with ECMAScript6
Up & running with ECMAScript6Up & running with ECMAScript6
Up & running with ECMAScript6
 
Adventures with Angular 2
Adventures with Angular 2Adventures with Angular 2
Adventures with Angular 2
 
Angular2
Angular2Angular2
Angular2
 
Webstorm
WebstormWebstorm
Webstorm
 
Angularjs - lazy loading techniques
Angularjs - lazy loading techniques Angularjs - lazy loading techniques
Angularjs - lazy loading techniques
 
Angular2 inter3
Angular2 inter3Angular2 inter3
Angular2 inter3
 
Webpack and angularjs
Webpack and angularjsWebpack and angularjs
Webpack and angularjs
 

Similar to How Angular2 Can Improve Your AngularJS Apps Today!

Ultimate Introduction To AngularJS
Ultimate Introduction To AngularJSUltimate Introduction To AngularJS
Ultimate Introduction To AngularJSJacopo Nardiello
 
MEAN - Notes from the field (Full-Stack Development with Javascript)
MEAN - Notes from the field (Full-Stack Development with Javascript)MEAN - Notes from the field (Full-Stack Development with Javascript)
MEAN - Notes from the field (Full-Stack Development with Javascript)Chris Clarke
 
AngularJS Testing Strategies
AngularJS Testing StrategiesAngularJS Testing Strategies
AngularJS Testing Strategiesnjpst8
 
Building an End-to-End AngularJS Application
Building an End-to-End AngularJS ApplicationBuilding an End-to-End AngularJS Application
Building an End-to-End AngularJS ApplicationDan Wahlin
 
CFCouchbase 2.0 and N1QL
CFCouchbase 2.0 and N1QLCFCouchbase 2.0 and N1QL
CFCouchbase 2.0 and N1QLAaron Benton
 
Introduction to Zend Framework web services
Introduction to Zend Framework web servicesIntroduction to Zend Framework web services
Introduction to Zend Framework web servicesMichelangelo van Dam
 
2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando...
2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando...2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando...
2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando...PHP Conference Argentina
 
Bonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node jsBonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node jsFrancois Zaninotto
 
AngularJS, More Than Directives !
AngularJS, More Than Directives !AngularJS, More Than Directives !
AngularJS, More Than Directives !Gaurav Behere
 
JavaScript Fundamentals with Angular and Lodash
JavaScript Fundamentals with Angular and LodashJavaScript Fundamentals with Angular and Lodash
JavaScript Fundamentals with Angular and LodashBret Little
 
Inversion Of Control
Inversion Of ControlInversion Of Control
Inversion Of ControlChad Hietala
 
Understanding backbonejs
Understanding backbonejsUnderstanding backbonejs
Understanding backbonejsNick Lee
 
Coffee@DBG - Exploring Angular JS
Coffee@DBG - Exploring Angular JSCoffee@DBG - Exploring Angular JS
Coffee@DBG - Exploring Angular JSDeepu S Nath
 

Similar to How Angular2 Can Improve Your AngularJS Apps Today! (20)

Ultimate Introduction To AngularJS
Ultimate Introduction To AngularJSUltimate Introduction To AngularJS
Ultimate Introduction To AngularJS
 
AngularJs
AngularJsAngularJs
AngularJs
 
MEAN - Notes from the field (Full-Stack Development with Javascript)
MEAN - Notes from the field (Full-Stack Development with Javascript)MEAN - Notes from the field (Full-Stack Development with Javascript)
MEAN - Notes from the field (Full-Stack Development with Javascript)
 
AngularJS Testing Strategies
AngularJS Testing StrategiesAngularJS Testing Strategies
AngularJS Testing Strategies
 
Building an End-to-End AngularJS Application
Building an End-to-End AngularJS ApplicationBuilding an End-to-End AngularJS Application
Building an End-to-End AngularJS Application
 
Min-Maxing Software Costs
Min-Maxing Software CostsMin-Maxing Software Costs
Min-Maxing Software Costs
 
Angular Workshop_Sarajevo2
Angular Workshop_Sarajevo2Angular Workshop_Sarajevo2
Angular Workshop_Sarajevo2
 
CFCouchbase 2.0 and N1QL
CFCouchbase 2.0 and N1QLCFCouchbase 2.0 and N1QL
CFCouchbase 2.0 and N1QL
 
Cf Couchbase 2.0-and-N1-QL
Cf Couchbase 2.0-and-N1-QLCf Couchbase 2.0-and-N1-QL
Cf Couchbase 2.0-and-N1-QL
 
Introduction to Zend Framework web services
Introduction to Zend Framework web servicesIntroduction to Zend Framework web services
Introduction to Zend Framework web services
 
AngularJS.part1
AngularJS.part1AngularJS.part1
AngularJS.part1
 
Zend framework service
Zend framework serviceZend framework service
Zend framework service
 
Zend framework service
Zend framework serviceZend framework service
Zend framework service
 
2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando...
2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando...2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando...
2013 - Nate Abele: HTTP ALL THE THINGS: Simplificando aplicaciones respetando...
 
Bonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node jsBonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node js
 
AngularJS, More Than Directives !
AngularJS, More Than Directives !AngularJS, More Than Directives !
AngularJS, More Than Directives !
 
JavaScript Fundamentals with Angular and Lodash
JavaScript Fundamentals with Angular and LodashJavaScript Fundamentals with Angular and Lodash
JavaScript Fundamentals with Angular and Lodash
 
Inversion Of Control
Inversion Of ControlInversion Of Control
Inversion Of Control
 
Understanding backbonejs
Understanding backbonejsUnderstanding backbonejs
Understanding backbonejs
 
Coffee@DBG - Exploring Angular JS
Coffee@DBG - Exploring Angular JSCoffee@DBG - Exploring Angular JS
Coffee@DBG - Exploring Angular JS
 

More from Nir Kaufman

Angular Dependency Injection
Angular Dependency InjectionAngular Dependency Injection
Angular Dependency InjectionNir Kaufman
 
Angular Prestige: Less-known API and techniques
Angular Prestige: Less-known API and techniquesAngular Prestige: Less-known API and techniques
Angular Prestige: Less-known API and techniquesNir Kaufman
 
Angular CLI custom builders
Angular CLI custom buildersAngular CLI custom builders
Angular CLI custom buildersNir Kaufman
 
Electronic music 101 for developers
Electronic music 101 for developersElectronic music 101 for developers
Electronic music 101 for developersNir Kaufman
 
Nestjs MasterClass Slides
Nestjs MasterClass SlidesNestjs MasterClass Slides
Nestjs MasterClass SlidesNir Kaufman
 
Angular EE - Special Workshop by Nir Kaufman
Angular EE - Special Workshop by Nir KaufmanAngular EE - Special Workshop by Nir Kaufman
Angular EE - Special Workshop by Nir KaufmanNir Kaufman
 
Decorators in js
Decorators in jsDecorators in js
Decorators in jsNir Kaufman
 
Styling recipes for Angular components
Styling recipes for Angular componentsStyling recipes for Angular components
Styling recipes for Angular componentsNir Kaufman
 
Introduction To Angular's reactive forms
Introduction To Angular's reactive formsIntroduction To Angular's reactive forms
Introduction To Angular's reactive formsNir Kaufman
 
AngularJS performance & production tips
AngularJS performance & production tipsAngularJS performance & production tips
AngularJS performance & production tipsNir Kaufman
 
Angular js - 10 reasons to choose angularjs
Angular js - 10 reasons to choose angularjs Angular js - 10 reasons to choose angularjs
Angular js - 10 reasons to choose angularjs Nir Kaufman
 
Angular js routing options
Angular js routing optionsAngular js routing options
Angular js routing optionsNir Kaufman
 

More from Nir Kaufman (13)

Angular Dependency Injection
Angular Dependency InjectionAngular Dependency Injection
Angular Dependency Injection
 
Angular Prestige: Less-known API and techniques
Angular Prestige: Less-known API and techniquesAngular Prestige: Less-known API and techniques
Angular Prestige: Less-known API and techniques
 
Angular CLI custom builders
Angular CLI custom buildersAngular CLI custom builders
Angular CLI custom builders
 
Electronic music 101 for developers
Electronic music 101 for developersElectronic music 101 for developers
Electronic music 101 for developers
 
Nestjs MasterClass Slides
Nestjs MasterClass SlidesNestjs MasterClass Slides
Nestjs MasterClass Slides
 
Angular EE - Special Workshop by Nir Kaufman
Angular EE - Special Workshop by Nir KaufmanAngular EE - Special Workshop by Nir Kaufman
Angular EE - Special Workshop by Nir Kaufman
 
Decorators in js
Decorators in jsDecorators in js
Decorators in js
 
Styling recipes for Angular components
Styling recipes for Angular componentsStyling recipes for Angular components
Styling recipes for Angular components
 
Introduction To Angular's reactive forms
Introduction To Angular's reactive formsIntroduction To Angular's reactive forms
Introduction To Angular's reactive forms
 
Angular redux
Angular reduxAngular redux
Angular redux
 
AngularJS performance & production tips
AngularJS performance & production tipsAngularJS performance & production tips
AngularJS performance & production tips
 
Angular js - 10 reasons to choose angularjs
Angular js - 10 reasons to choose angularjs Angular js - 10 reasons to choose angularjs
Angular js - 10 reasons to choose angularjs
 
Angular js routing options
Angular js routing optionsAngular js routing options
Angular js routing options
 

Recently uploaded

Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?Antenna Manufacturer Coco
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 

Recently uploaded (20)

Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 

How Angular2 Can Improve Your AngularJS Apps Today!

  • 1. HOW ANGULAR2 CAN IMPROVE YOUR ANGULARJS APPS TODAY! Nir Kaufman
  • 2. NIR KUFMN Nir Kaufman - Doing Angular for years - Wrote a book about Angular2 - Play the electric Bass Head of Angular Development @ 500Tech *This picture have been retouched the actual speaker may look different
  • 4.
  • 6. I AM NOT GOING TO TALK ABOUT - TypeScript - Angular2 upgrade module - Ng-forward library - Data flow (Redux, RxJs) - Angular 1.5 new Component API
  • 8. GET READY FOR THE MIGRATION
  • 14. IT WILL IMPROVE YOUR APP DESIGN
  • 15. AND GET YOU READY FOR THE FUTURE
  • 17. I WILL TALK ABOUT - Embracing Modules - Using Classes - Decoupling from Framework API - Components as UI building blocks
  • 22. THAT YOU CAN COMPLETE IN ONE SPRINT
  • 23.
  • 26. EVERYTHING IS A MODULE $ git checkout 01_modules
  • 27. USE A MODULE LOADER Integrate a module bundler and an ES6 compiler to use javaScript modules. http://webpack.github.io/
  • 29. module.exports = {
 entry: 'index.js',
 
 // configure loaders
 module: {
 loaders: [
 {
 test: /.js$/,
 exclude: /node_modules/,
 loader: "babel",
 query: {presets: ['es2015', 'stage-1']}
 },
 
 // load css as inline styles
 {test: /.css$/, loader: "style!css"}
 ]
 }
 }; new webpack.config.js
  • 30. <script src="bundle.js"></script> old index.html <!-- load core scripts -->
 <script src="../node_modules/angular/angular.js"></script>
 <script src="../node_modules/angular-ui-router/release/angular-ui- router.js"></script>
 <script src="index.js"></script>
 
 <!-- load services -->
 <script src="services/logger.factory.js"></script>
 <script src="services/storage.service.js"></script>
 <script src="services/orders.service.js"></script>
 
 <!-- load filters -->
 <script src="filters/paid-orders.filter.js"></script>
 
 <!-- load directives -->
 <script src="directives/simple-table/simple-table.js"></script>
 
 <!-- load controllers -->
 <script src="states/home.controller.js"></script>
 <script src="states/log.controller.js"></script>
  • 31. <body> <script src=“bundle.js"></script> </body> new index.html import 'angular';
 import 'angular-ui-router';
 import './assets/index.css';
 
 
 import services from './services/services.module';
 import filters from './filters/filters.module'
 import directives from './directives/directives.module';
 import states from './states/state.module'; new index.js
  • 33. old log.controller.js (function (angular) {
 
 angular.module('app')
 .controller('LogController', function ($scope, $window, Orders, Storage) {
 $scope.orders = Orders.getOrders();
 
 $scope.clearHistory = function () {
 
 if ($scope.orders.length === 0) {
 return;
 }
 
 var result = $window.confirm("Clear History?");
 if (result) {
 Storage.clear();
 $scope.orders = [];
 }
 }
 })
 
 }(window.angular));
  • 34. new log.controller.js export function LogController ($scope, $window, Orders, Storage) {
 
 $scope.orders = Orders.getOrders();
 
 $scope.clearHistory = function () {
 
 if ($scope.orders.length === 0) {
 return;
 }
 
 var result = $window.confirm("Clear History?");
 if (result) {
 Storage.clear();
 $scope.orders = [];
 }
 }
 }
  • 36. old storage.service.js (function (angular) { 
 angular.module('app')
 .service('Storage', function () {
 
 var ORDERS_KEY = "ORDERS";
 this.store = localStorage;
 
 this.getOrders = function () {
 return JSON.parse(this.store.getItem(ORDERS_KEY)) || [];
 };
 
 this.saveOrders = function (orders) {
 this.store.setItem(ORDERS_KEY, JSON.stringify(orders))
 };
 
 this.clear = function () {
 this.store.clear();
 }
 }) 
 }(window.angular));
  • 37. new storage.service.js export function Storage () {
 
 var ORDERS_KEY = "ORDERS";
 this.store = localStorage;
 
 this.getOrders = function () {
 return JSON.parse(this.store.getItem(ORDERS_KEY)) || [];
 };
 
 this.saveOrders = function (orders) {
 this.store.setItem(ORDERS_KEY, JSON.stringify(orders))
 };
 } import {Storage} from './storage.service';
 
 export default angular.module('services', [])
 .service('Storage', Storage) new service.module.js
  • 38. old index.js (function (angular) {
 
 angular.module('app', ['ui.router'])
 .config(function ($stateProvider, $urlRouterProvider) {
 
 $urlRouterProvider.otherwise("/");
 
 $stateProvider
 .state('home', {
 url: '/',
 templateUrl: 'templates/home.html',
 controller: 'HomeController'
 })
 .state('log', {
 url: '/log',
 templateUrl: 'templates/log.html',
 controller: 'LogController'
 })
 }); 
 }(window.angular)
  • 39. new index.js import 'angular';
 import 'angular-ui-router';
 import ‘./assets/index.css'; 
 import services from './services/services.module';
 import filters from './filters/filters.module'
 import directives from './directives/directives.module';
 import states from './states/state.module';
 import {routes} from './config/routes';
 
 angular.module('app', [
 'ui.router',
 services.name,
 directives.name,
 filters.name,
 states.name ]).config(routes);
 
 // bootstrap angular
 angular.element(document).ready(function () {
 angular.bootstrap(document, ['app']);
 });
  • 40. new routes.js export function routes($stateProvider, $urlRouterProvider) {
 
 $urlRouterProvider.otherwise("/");
 
 // configure application routes
 $stateProvider
 .state('home', {
 url: '/',
 templateUrl: 'templates/home.html',
 controller: 'HomeController'
 })
 
 .state('log', {
 url: '/log',
 templateUrl: 'templates/log.html',
 controller: 'LogController'
 })
 }
  • 41. EVERYTHING IS A CLASS $ git checkout 02_classes
  • 42. MOVE FORWARD TO ES6 You can adopt the new syntax slowly. Start by using classes instead of functions. http://babeljs.io/
  • 44. old storage.service.js export function Storage () {
 
 var ORDERS_KEY = "ORDERS";
 this.store = localStorage;
 
 this.getOrders = function () {
 return JSON.parse(this.store.getItem(ORDERS_KEY)) || [];
 };
 
 this.saveOrders = function (orders) {
 this.store.setItem(ORDERS_KEY, JSON.stringify(orders))
 };
 }
  • 45. new storage.service.js export class Storage {
 
 constructor() {
 this.ORDERS_KEY = "ORDERS";
 this.store = localStorage;
 }
 
 getOrders() {
 return JSON.parse(this.store.getItem(this.ORDERS_KEY)) || [];
 };
 
 saveOrders(orders) {
 this.store.setItem(this.ORDERS_KEY, JSON.stringify(orders))
 };
 }
  • 47. old paid-orders.filter.js export function paidOrders() { 
 return function (orders) {
 return orders.filter(order => order.paid === false)
 } 
 } import {paidOrders} from './paid-orders.filter';
 
 export default angular.module('filters', [])
 .filter('paidOrders',paidOrders); old filters.module.js
  • 48. new paid-orders.filter.js export class PaidOrders {
 
 static transform () {
 return (orders) => orders.filter(order => order.paid === false)
 }
 } import {PaidOrders} from './paid-orders.filter';
 
 export default angular.module('filters', [])
 .filter('paidOrders', PaidOrders.transform); new filters.module.js
  • 50. old log.controller.js export function LogController ($scope, $window, Orders, Storage) {
 
 $scope.orders = Orders.getOrders();
 
 $scope.clearHistory = function () {
 
 if ($scope.orders.length === 0) {
 return;
 }
 
 var result = $window.confirm("Clear History?");
 if (result) {
 Storage.clear();
 $scope.orders = [];
 }
 }
 }
  • 51. new log.controller.js export class LogController {
 
 constructor($scope, $window, Orders, Storage) {
 $scope.orders = Orders.getOrders();
 
 $scope.clearHistory = function () {
 
 if ($scope.orders.length === 0) {
 return;
 }
 
 const result = $window.confirm("Clear History?");
 
 if (result) {
 Storage.clear();
 $scope.orders = [];
 }
 }
 }
 }
  • 53. MORE JAVASCRIPT LESS ANGULAR Bind to the controller instance, use setters for watching changes, free yourself from $scope events
  • 54. CLASS SYNTAX $ git checkout 03_drop_the_scope
  • 55. old log.controller.js export class LogController {
 
 constructor($scope, $window, Orders, Storage) {
 $scope.orders = Orders.getOrders();
 
 $scope.clearHistory = function () {
 
 if ($scope.orders.length === 0) {
 return;
 }
 
 const result = $window.confirm("Clear History?");
 
 if (result) {
 Storage.clear();
 $scope.orders = [];
 }
 }
 }
  • 56. old routes.js export function routes($stateProvider, $urlRouterProvider) {
 
 $urlRouterProvider.otherwise("/");
 
 $stateProvider
 .state('log', {
 url: '/log',
 templateUrl: 'templates/log.html',
 controller: 'LogController'
 })
 } <div class="container-fluid">
 <div class="row">
 <div class="container-fluid">
 <span ng-click="clearHistory()"><i>clear history</i></span>
 <br/>
 <simple-table orders="orders"></simple-table>
 </div>
 </div>
 </div> old log.html
  • 57. new log.controller.js export class LogController {
 
 constructor( $window, Orders, Storage) {
 this.window = $window;
 this.store = Storage;
 this.orders = Orders.getOrders();
 }
 
 clearHistory = function () {
 
 if (this.orders.length === 0) {
 return;
 }
 
 const result = this.window.confirm("Clear History?");
 
 if (result) {
 this.store.clear();
 this.orders = [];
 }
 }
 }
  • 58. new routes.js export function routes($stateProvider, $urlRouterProvider) {
 
 $urlRouterProvider.otherwise("/");
 
 $stateProvider
 .state('log', {
 url: '/log',
 templateUrl: 'templates/log.html',
 controller: ‘LogController as Logs'
 })
 } <div class="container-fluid">
 <div class="row">
 <div class="container-fluid">
 <span ng-click="Logs.clearHistory()"><i>clear history</i></span>
 <br/>
 <simple-table orders="Logs.orders"></simple-table>
 </div>
 </div>
 </div> new log.html
  • 59. WATCH CHANGES $ git checkout 04_watch_for_changes
  • 60. SHALLOW WATCH? JUST USE SETTERS. $ git checkout 05_getters_setters
  • 61. old home.controller.js export class HomeController {
 
 constructor(Orders, $scope) {
 this.Orders = Orders;
 this.menu = this.Orders.getMenuItems();
 this.orders = this.Orders.getOrders();
 this.selectedOrder = null;
 
 $scope.$watch(()=>this.selectedOrder, this.changeHandler)
 }
 
 changeHandler(newVal,oldVal){
 console.log('New order Was selected!');
 console.log(newVal, oldVal);
 }
 }
  • 62. new home.controller.js export class HomeController {
 
 constructor(Orders) {
 this.Orders = Orders;
 this.menu = this.Orders.getMenuItems();
 this.orders = this.Orders.getOrders();
 this._selectedOrder = null;
 }
 
 set selectedOrder(order){ this.changeHandler(order);
 this._selectedOrder = order; 
 }
 
 changeHandler(newVal){
 console.log('New order Was selected!');
 console.log(newVal);
 }
 }
  • 63. DEEP WATCHING? THINK IMMUTABLE. $ git checkout 06_be_immutable
  • 64. old home.controller.js export class HomeController {
 
 constructor(Orders) {
 this.Orders = Orders;
 this.menu = this.Orders.getMenuItems();
 this.orders = this.Orders.getOrders();
 this.selectedOrder = null;
 }
 
 createOrder(clientName) {
 const order = this.Orders.createOrder(clientName);
 this.clientName = '';
 this.selectOrder(order);
 }; }
  • 65. new home.controller.js export class HomeController {
 
 constructor(Orders) {
 this.Orders = Orders;
 this.menu = this.Orders.getMenuItems();
 this._orders = this.Orders.getOrders();
 this.selectedOrder = null;
 }
 
 set orders(orders) {
 console.log('orders changed!', orders);
 this._orders = orders;
 }
 
 createOrder(clientName) {
 const order = this.Orders.createOrder(clientName);
 this.orders = this.Orders.getOrders();
 this.clientName = '';
 this.selectOrder(order);
 }; }
  • 66. EMITTING EVENTS $ git checkout 07_event_emitter
  • 67. new dispatcher.js export class Dispatcher {
 
 constructor() {
 this.subjects = {};
 }
 
 emit(event, payload){
 this.validate(event);
 this.subjects[event].forEach( callback => callback.apply(null, payload))
 }
 
 on(event, callback){
 this.validate(event);
 this.subjects[event].push(callback);
 }
 
 validate(event){
 if(!this.subjects[event]) {
 this.subjects[event] = [];
 }
 }
 }
  • 68. new storage.service.js export class Storage {
 
 constructor(Dispatcher) {
 this.ORDERS_KEY = "ORDERS";
 this.store = localStorage;
 this.dispatcher = Dispatcher;
 }
 
 getOrders() {
 return JSON.parse(this.store.getItem(this.ORDERS_KEY)) || [];
 };
 
 saveOrders(orders) {
 this.store.setItem(this.ORDERS_KEY, JSON.stringify(orders))
 this.dispatcher.emit('ORDERS_SAVED', orders);
 };
 
 clear() {
 this.store.clear();
 }
 }
  • 69. new logger.factory.js export class Logger {
 
 constructor($log, Dispatcher) {
 this.$log = $log;
 this.timeStamp = new Date().toString();
 
 Dispatcher.on('ORDERS_SAVED', function (data) {
 this.debug(`storage saved the orders!`);
 console.log(data);
 })
 }
 
 debug(msg) {
 this.$log.debug(this.timeStamp + ": " + msg)
 }
 
 log(msg) {
 this.$log.log(msg)
 }
 }
  • 71. COMPOSE COMPONENTS Break the UI layer into small, maintainable and reusable building blocks.
  • 72. HOME ORDERS LIST ORDER EDITOR NEW ORDER FORM ORDER LIST ORDER FORM NO ORDER EDIT ORDER FORM ORDER ITEM LIST EDITOR FOOTER
  • 73. PROJECT SRTUCTURE $ git checkout 08_group_by_feature
  • 74. old structure new structure
  • 75. new home.module.js import {HomeController} from './home.controller';
 
 function routes($stateProvider) {
 $stateProvider
 .state('home', {
 url: '/',
 templateUrl: 'home/home.html',
 controller: 'HomeController as Home'
 })
 }
 
 export default angular.module('home', [])
 .config(routes)
 .controller({HomeController});

  • 76. DIRECTIVES AS COMPONENTS $ git checkout 09_directives_as_components
  • 78. new home.module.js function routes($stateProvider) {
 $stateProvider
 .state('home', {
 url: '/',
 template: '<home></home>'
 })
 }
 
 export default angular.module('home', [])
 .config(routes)
 .filter('paidOrders', PaidOrders.transform)
 .directive({
 home,
 newOrderForm,
 orderList,
 ordersList,
 noSelectedOrder,
 editOrderForm,
 orderItemList,
 orderEditorFooter,
 orderEditor
 });
  • 79. new home.js export function home () {
 return {
 template: `
 <div class="container-fluid">
 <div class="row">
 <orders-list></orders-list>
 <order-editor></order-editor>
 </div>
 </div>
 `,
 controller: HomeController,
 controllerAs: 'Home'
 }
 }
  • 80. new order-list.js export function ordersList() {
 return {
 template: `
 <div class="col-sm-6">
 <new-order-form></new-order-form>
 <br/>
 <order-list></order-list>
 </div>
 `
 }
 }

  • 81. new order-editor.js export function orderEditor() {
 return {
 template: `
 <div class="col-sm-6">
 
 <no-selected-order></no-selected-order>
 
 <div class="card" ng-if="Home.selectedOrder">
 <div class="card-block">
 <edit-order-form></edit-order-form>
 <order-item-list></order-item-list>
 <order-editor-footer></order-editor-footer>
 </div>
 </div>
 </div>
 `
 }
 }
  • 82. new no-selected-order.js export function noSelectedOrder () {
 return {
 template: `
 <div class="card" ng-if="!Home.selectedOrder">
 <div class="card-block">
 <h4 class="card-title">No order selected.</h4>
 </div>
 </div>
 `
 }
 }
  • 83. new order-list-item.js export function orderItemList () {
 return {
 template:`
 <ul class="list-group list-group-flush">
 <li class="list-group-item"
 ng-repeat="menuItem in Home.selectedOrder.items">
 <span class="label label-default label-pill pull-xs-right">
 {{menuItem.itemPrice}}</span>
 {{menuItem.itemName}}
 </li>
 </ul>
 `
 }
 }
  • 85. MODULAR AND CLEAN CODE IS ALWAYS BETTER
  • 90. THANKS ROME 18-19 MARCH 2016 Nir@500tech.com
 @nirkaufman on twitter slideshare.net/nirkaufman/ github.com/nirkaufman All pictures belong to their respective authors