99
The Ultimate Introduction to AngularJS

Ultimate Introduction To AngularJS

Embed Size (px)

DESCRIPTION

The ultimate introduction to AngularJS with an overview on testing

Citation preview

Page 1: Ultimate Introduction To AngularJS

The Ultimate Introduction to

AngularJS

Page 2: Ultimate Introduction To AngularJS

Jacopo NardielloPadawan Programmer

Twitter: @jnardiello

Page 3: Ultimate Introduction To AngularJS

Practicing the force at

Page 4: Ultimate Introduction To AngularJS

What Angular is NOT

Page 5: Ultimate Introduction To AngularJS

“AngularJS is not jQuery”

What Angular is NOT

Page 6: Ultimate Introduction To AngularJS

Framework != Library

Page 7: Ultimate Introduction To AngularJS

“A framework embodies some abstract design, with more behavior built in.”

! - M. Fowler

Page 8: Ultimate Introduction To AngularJS

MVC MVVMvs

Page 9: Ultimate Introduction To AngularJS

What is Angular

Superheroic JavaScript MVW Framework

Page 10: Ultimate Introduction To AngularJS

What is Angular

Superheroic JavaScript MVW Framework

Model

Page 11: Ultimate Introduction To AngularJS

What is Angular

Superheroic JavaScript MVW Framework

ViewModel

Page 12: Ultimate Introduction To AngularJS

What is Angular

Superheroic JavaScript MVW Framework

ViewModel

Whatever (works for you)

Page 13: Ultimate Introduction To AngularJS

Zen of Angular

Page 14: Ultimate Introduction To AngularJS

#1“It is a very good idea to decouple

DOM manipulation from app logic.”

Page 15: Ultimate Introduction To AngularJS

#2“It is a really, really good idea to regard app testing as equal in importance to

app writing”

Page 16: Ultimate Introduction To AngularJS

#3“It is an excellent idea to decouple the client side of an app from the server

side”

Page 17: Ultimate Introduction To AngularJS

Elements of an Angular App

Page 18: Ultimate Introduction To AngularJS

Bootstrapping an App

<body ng-app=“car">

Page 19: Ultimate Introduction To AngularJS

JS bootstrap code

angular.module('car', [ 'car.service', 'car.directive', ‘car.controller’ ])

Page 20: Ultimate Introduction To AngularJS

JS bootstrap code

angular.module('car', [ 'car.service', 'car.directive', ‘car.controller’ ])

Page 21: Ultimate Introduction To AngularJS

JS bootstrap code

angular.module('car', [ 'car.service', 'car.directive', ‘car.controller’ ])

Page 22: Ultimate Introduction To AngularJS

JS bootstrap code

angular.module('car', [ 'car.service', 'car.directive', ‘car.controller’ ])

Page 23: Ultimate Introduction To AngularJS

Angular is modular

angular.module('car.service', […])

angular.module(‘car.directives', […])

Page 24: Ultimate Introduction To AngularJS

Extending the DOM

Angular extends DOM behavior using Directives

Page 25: Ultimate Introduction To AngularJS

Directivesangular.module('greetApp', []) .directive(‘greetMe’, function() { return { template: ‘<h1>Hello</h1>’ } })

Page 26: Ultimate Introduction To AngularJS

angular.module('greetApp', []) .directive(‘greetMe’, function() { return { template: ‘<h1>Hello</h1>’ } })

Directives

Page 27: Ultimate Introduction To AngularJS

js

html <div greet-me></div>

angular.module('greetApp', []) .directive(‘greetMe’, function() { return { template: ‘<h1>Hello</h1>’ } })

Directives

Page 28: Ultimate Introduction To AngularJS

Adding logic to directives.directive('myCoffeeMachine', [ ‘$interval’, ‘water’, ‘pump’, function($interval, dateFilter) { return { restrict: 'AE', link: function(scope, element, attrs) { coffee = $interval(function() { prepareCoffee(); // update DOM }, n0000); } }]);

Page 29: Ultimate Introduction To AngularJS

Adding logic to directives.directive('myCoffeeMachine', [ ‘$interval’, ‘water’, ‘pump’, function($interval, dateFilter) { return { restrict: ‘AE', link: function(scope, element, attrs) { coffee = $interval(function() { prepareCoffee(); // update DOM }, n0000); } }]);

Page 30: Ultimate Introduction To AngularJS

Adding logic to directives.directive('myCoffeeMachine', [ ‘$interval’, ‘water’, ‘pump’, function($interval, dateFilter) { return { restrict: 'AE', link: function(scope, element, attrs) { coffee = $interval(function() { prepareCoffee(); }, n0000); } }]);

Page 31: Ultimate Introduction To AngularJS

Reusable element

.directive('myCoffeeMachine', [ ‘$interval’, ‘water’, ‘pump’, function($interval, dateFilter) { return { restrict: 'AE', link: function(scope, element, attrs) { coffee = $interval(function() { prepareCoffee(); // update DOM }, n0000); } }]);

<my-coffee-machine></..>

Page 32: Ultimate Introduction To AngularJS

Controllers

“A Controller is a JavaScript constructor function that is used to augment the Angular

Scope”

Page 33: Ultimate Introduction To AngularJS

Controllers

“A Controller is a JavaScript constructor function that is used to augment the Angular

Scope”

Page 34: Ultimate Introduction To AngularJS

A step back: ScopesScope ~ Model ~ Current state

Page 35: Ultimate Introduction To AngularJS

A step back: ScopesScope ~ Model ~ Current state

Scopes are objects organized hierarchically, aimed to mimic the DOM structure

Page 36: Ultimate Introduction To AngularJS

A step back: Scopes

Each module instantiate a rootScope object

Scope ~ Model ~ Current state

Scopes are objects organized hierarchically, aimed to mimic the DOM structure

Page 37: Ultimate Introduction To AngularJS

A step back: Scopes

Page 38: Ultimate Introduction To AngularJS

Controllersvar myApp = angular.module('myApp',[]); !

myApp.controller('GreetingController', [ '$scope', function($scope) { $scope.greeting = 'Hola!'; }]);

js

Page 39: Ultimate Introduction To AngularJS

Controllersvar myApp = angular.module('myApp',[]); !

myApp.controller('GreetingController', [ '$scope', function($scope) { $scope.greeting = 'Hola!'; }]);

<div ng-controller="GreetingController">

js

html

Page 40: Ultimate Introduction To AngularJS

Angular automagically keeps in sync the model inside controllers with views

Ultimate Data Binding

Page 41: Ultimate Introduction To AngularJS

myApp.controller('GreetingController', [ '$scope', function($scope) { $scope.greeting = 'Hola!'; }]);

<div ng-controller="GreetingController"> {{ greeting }} </div>

Ultimate Data Binding

js

html

Page 42: Ultimate Introduction To AngularJS

Behavior everywhere (and shared resources)

What if you want to declare a class, an object or a function and have it available everywhere?

Page 43: Ultimate Introduction To AngularJS

Behavior everywhere (and shared resources)

Factories

Page 44: Ultimate Introduction To AngularJS

Behavior everywhere (and shared resources)

Factories

Services

Page 45: Ultimate Introduction To AngularJS

Factory Example.factory(‘addOne', function($window) { var sum = 0 return function(sum) { sum++ $window.alert(sum) } })

Page 46: Ultimate Introduction To AngularJS

.factory(‘addOne', function($window) { var sum = 0 return function(sum) { sum++ $window.alert(sum) } })

Factory Example

Page 47: Ultimate Introduction To AngularJS

Behavior everywhere (and shared resources)

Factories

Services

returned value of function

instance

Page 48: Ultimate Introduction To AngularJS

Mounting all the pieces

Page 49: Ultimate Introduction To AngularJS

Testing Angular

Page 50: Ultimate Introduction To AngularJS

Misko Hevery

“Agile Coach at Google where he is responsible for coaching Googlers to maintain the high level of automated testing culture”

- misko.hevery.com/about/

Page 51: Ultimate Introduction To AngularJS

Misko Hevery

+

Page 52: Ultimate Introduction To AngularJS

“Angular is written with testability in mind”

- Angular Doc

Page 53: Ultimate Introduction To AngularJS

Why is Angular easily testable?

Page 54: Ultimate Introduction To AngularJS

Dependency Injection

Page 55: Ultimate Introduction To AngularJS

DI

As a Pattern Framework

Page 56: Ultimate Introduction To AngularJS

DI as Patternfunction Car() { var wheel = new Wheel(); var engine = Engine.getInstance(); var door = app.get(‘Door’); ! this.move = function() { engine.on(); wheel.rotate(); door.open(); } }

Page 57: Ultimate Introduction To AngularJS

DI as Patternfunction Car() { var wheel = new Wheel(); var engine = Engine.getInstance(); var door = app.get(‘Door’); ! this.move = function() { engine.on(); wheel.rotate(); door.open(); } }

Page 58: Ultimate Introduction To AngularJS

DI as Pattern

function Car(wheel, engine, door) { this.move = function() { engine.on(); wheel.rotate(); door.open(); } }

Page 59: Ultimate Introduction To AngularJS

The problemfunction main() { var fuel = new Fuel(); var electricity = new Electricity(); var engine = new Engine(fuel); var door = new Door(Electricity); var wheel = new Wheel(); var car = new Car(wheel, engine, door); car.move(); }

Page 60: Ultimate Introduction To AngularJS

The problemfunction main() { var fuel = new Fuel(); var electricity = new Electricity(); var engine = new Engine(fuel); var door = new Door(Electricity); var wheel = new Wheel(); var car = new Car(wheel, engine, door); car.move(); }

Page 61: Ultimate Introduction To AngularJS

The problemfunction main() { var fuel = new Fuel(); var electricity = new Electricity(); var engine = new Engine(fuel); var door = new Door(Electricity); var wheel = new Wheel(); var car = new Car(wheel, engine, door); car.move(); }

Page 62: Ultimate Introduction To AngularJS

The problemfunction main() { var fuel = new Fuel(); var electricity = new Electricity(); var engine = new Engine(fuel); var door = new Door(Electricity); var wheel = new Wheel(); var car = new Car(wheel, engine, door); car.move(); }

Page 63: Ultimate Introduction To AngularJS

DI as frameworkfunction main() { var injector = new Injector(….); var car = injector.get(Car); car.move(); }

Page 64: Ultimate Introduction To AngularJS

DI as frameworkfunction main() { var injector = new Injector(….); var car = injector.get(Car); car.move(); }

Car.$inject = [‘wheel’, ‘engine’, ‘door’]; function Car(wheel, engine, door) { this.move = function() { … } }

Page 65: Ultimate Introduction To AngularJS

DI as frameworkfunction main() { var injector = new Injector(….); var car = injector.get(Car); car.move(); }

Car.$inject = [‘wheel’, ‘engine’, ‘door’]; function Car(wheel, engine, door) { this.move = function() { … } }

Page 66: Ultimate Introduction To AngularJS

Angular testability is super-heroic!

but…

Page 67: Ultimate Introduction To AngularJS

“you still have to do the right thing.”- Angular Doc

Page 68: Ultimate Introduction To AngularJS

Testability

1. Don’t use new2. Don’t use globals

Page 69: Ultimate Introduction To AngularJS

The Angular Way

Page 70: Ultimate Introduction To AngularJS

Solid structured code

Page 71: Ultimate Introduction To AngularJS

Testing components

Page 72: Ultimate Introduction To AngularJS

Controllerfunction RocketCtrl($scope) { $scope.maxFuel = 100; $scope.finalCheck = function() { if ($scope.currentFuel < $scope.maxFuel) { $scope.check = ‘ko’; } else { $scope.check = 'ok'; } }; }

Page 73: Ultimate Introduction To AngularJS

Controllerfunction RocketCtrl($scope) { $scope.maxFuel = 100; $scope.finalCheck = function() { if ($scope.currentFuel < $scope.maxFuel) { $scope.check = ‘ko’; } else { $scope.check = 'ok'; } }; }

Page 74: Ultimate Introduction To AngularJS

var $scope = {}; var rc = $controller( 'RocketCtrl', { $scope: $scope } ); !$scope.currentFuel = 80; $scope.finalCheck(); expect($scope.check).toEqual('ko');

Controller Test

Page 75: Ultimate Introduction To AngularJS

Directiveapp.directive('rocketLaunchPad', function () { return { restrict: 'AE', replace: true, template: ‘<rocket-launch-pad> Rocket here <rocket-launch-pad>’ }; });

Page 76: Ultimate Introduction To AngularJS

Directive Test

it(‘Check launchpad was installed', function() { var element = $compile(“<rocket-launch-pad></rocket-launch-pad>”)($rootScope); ! expect(element.html()).toContain("Rocket here"); });

Page 77: Ultimate Introduction To AngularJS

Tools

Page 78: Ultimate Introduction To AngularJS
Page 79: Ultimate Introduction To AngularJS

Karma

Protractor

Page 80: Ultimate Introduction To AngularJS

Test Runner

Page 81: Ultimate Introduction To AngularJS

Karma

Run tests against real browsers

Page 82: Ultimate Introduction To AngularJS

Karma

Run tests against real browsers

Unit tests

Page 83: Ultimate Introduction To AngularJS

Config file> karma init

Page 84: Ultimate Introduction To AngularJS

Config file> karma init

- frameworks: [‘jasmine’]

Page 85: Ultimate Introduction To AngularJS

Config file> karma init

- frameworks: [‘jasmine’]- autoWatch: true

Page 86: Ultimate Introduction To AngularJS

Config file> karma init

- frameworks: [‘jasmine’]

- files: [ ‘../tests/controllerSpec.js’ ],

- autoWatch: true

Page 87: Ultimate Introduction To AngularJS

Config file> karma init

- frameworks: [‘jasmine’]

- files: [ ‘../tests/controllerSpec.js’ ],

- autoWatch: true

- browsers: ['Chrome']

Page 88: Ultimate Introduction To AngularJS

Using Karma> karma start config.js

Page 89: Ultimate Introduction To AngularJS

Using Karma> karma start config.js

Page 90: Ultimate Introduction To AngularJS

ProtractorE2E Angular Testing

Angular wrapper for WebDriver

Page 91: Ultimate Introduction To AngularJS

Anatomy of a E2E testdescribe(‘…’, function() { it(‘…’, function() { browser.get(‘…’); element(by.model(‘…’)).sendKeys(..); ! var calculate = element(by.binding(‘…’)); ! expect(some.method()).toEqual(..); }); });

Page 92: Ultimate Introduction To AngularJS

Global Variablesdescribe(‘…’, function() { it(‘…’, function() { browser.get(‘…’); element(by.model(‘…’)).sendKeys(..); ! var calculate = element(by.binding(‘…’)); ! expect(some.method()).toEqual(..); }); });

Page 93: Ultimate Introduction To AngularJS

Global Variablesdescribe(‘…’, function() { it(‘…’, function() { browser.get(‘…’); element(by.model(‘…’)).sendKeys(..); ! var calculate = element(by.binding(‘…’)); ! expect(some.method()).toEqual(..); }); });

Super-Happy Panda!

Page 94: Ultimate Introduction To AngularJS

Page Objects

Protractor provides

Page 95: Ultimate Introduction To AngularJS

Page Objects

Protractor provides

Debugging with superpowers

Page 96: Ultimate Introduction To AngularJS

Page Objects

Protractor provides

Debugging with superpowersAngular-specific functions

Page 97: Ultimate Introduction To AngularJS
Page 98: Ultimate Introduction To AngularJS

Final Thoughts

Page 99: Ultimate Introduction To AngularJS

Jacopo NardielloTwitter: @jnardiello

Questions?