The Ultimate
Introduction to
AngularJS
Jacopo Nardiello
Padawan Programmer
Twitter: @jnardiello
Practicing the force at
What Angular is NOT
“AngularJS is not jQuery”
What Angular is NOT
Framework != Library
“A framework embodies some abstract
design, with more behavior built in.”
! - M. Fowler
MVC MVVMvs
What is Angular
Superheroic JavaScript MVW Framework
What is Angular
Superheroic JavaScript MVW Framework
Model
What is Angular
Superheroic JavaScript MVW Framework
View
Model
What is Angular
Superheroic JavaScript MVW Framework
View
Model
Whatever (works for you)
Zen of Angular
#1
“It is a very good idea to decouple
DOM manipulation from app logic.”
#2
“It is a really, really good idea to regard
app testing as equal in importance to
app writing”
#3
“It is an excellent idea to decouple the
client side of an app from the server
side”
Elements of an Angular App
Bootstrapping an App
<body ng-app=“car">
JS bootstrap code
angular.module('car', [
'car.service',
'car.directive',
‘car.controller’
])
JS bootstrap code
angular.module('car', [
'car.service',
'car.directive',
‘car.controller’
])
JS bootstrap code
angular.module('car', [
'car.service',
'car.directive',
‘car.controller’
])
JS bootstrap code
angular.module('car', [
'car.service',
'car.directive',
‘car.controller’
])
Angular is modular
angular.module('car.service', […])
angular.module(‘car.directives', […])
Extending the DOM
Angular extends DOM
behavior using Directives
Directives
angular.module('greetApp', [])
.directive(‘greetMe’, function() {
return {
template: ‘<h1>Hello</h1>’
}
})
angular.module('greetApp', [])
.directive(‘greetMe’, function() {
return {
template: ‘<h1>Hello</h1>’
}
})
Directives
js
html <div greet-me></div>
angular.module('greetApp', [])
.directive(‘greetMe’, function() {
return {
template: ‘<h1>Hel...
Adding logic to directives
.directive('myCoffeeMachine', [
‘$interval’,
‘water’,
‘pump’,
function($interval, dateFilter) {...
Adding logic to directives
.directive('myCoffeeMachine', [
‘$interval’,
‘water’,
‘pump’,
function($interval, dateFilter) {...
Adding logic to directives
.directive('myCoffeeMachine', [
‘$interval’,
‘water’,
‘pump’,
function($interval, dateFilter) {...
Reusable element
.directive('myCoffeeMachine', [
‘$interval’,
‘water’,
‘pump’,
function($interval, dateFilter) {
return {
...
Controllers
“A Controller is a JavaScript constructor
function that is used to augment the Angular
Scope”
Controllers
“A Controller is a JavaScript constructor
function that is used to augment the Angular
Scope”
A step back: Scopes
Scope ~ Model ~ Current state
A step back: Scopes
Scope ~ Model ~ Current state
Scopes are objects organized hierarchically,
aimed to mimic the DOM stru...
A step back: Scopes
Each module instantiate a rootScope object
Scope ~ Model ~ Current state
Scopes are objects organized ...
A step back: Scopes
Controllers
var myApp = angular.module('myApp',[]);
!
myApp.controller('GreetingController', [
'$scope',
function($scope) ...
Controllers
var myApp = angular.module('myApp',[]);
!
myApp.controller('GreetingController', [
'$scope',
function($scope) ...
Angular automagically keeps in sync
the model inside controllers with views
Ultimate Data Binding
myApp.controller('GreetingController', [
'$scope',
function($scope) {
$scope.greeting = 'Hola!';
}]);
<div ng-controller="...
Behavior everywhere
(and shared resources)
What if you want to declare a class, an object
or a function and have it availa...
Behavior everywhere
(and shared resources)
Factories
Behavior everywhere
(and shared resources)
Factories
Services
Factory Example
.factory(‘addOne', function($window) {
var sum = 0
return function(sum) {
sum++
$window.alert(sum)
}
})
.factory(‘addOne', function($window) {
var sum = 0
return function(sum) {
sum++
$window.alert(sum)
}
})
Factory Example
Behavior everywhere
(and shared resources)
Factories
Services
returned value
of function
instance
Mounting all the pieces
Testing Angular
Misko Hevery
“Agile Coach at Google where he is
responsible for coaching Googlers to
maintain the high level of automated
...
Misko Hevery
+
“Angular is written with
testability in mind”
- Angular Doc
Why is Angular easily
testable?
Dependency
Injection
DI
As a Pattern Framework
DI as Pattern
function Car() {
var wheel = new Wheel();
var engine = Engine.getInstance();
var door = app.get(‘Door’);
!
t...
DI as Pattern
function Car() {
var wheel = new Wheel();
var engine = Engine.getInstance();
var door = app.get(‘Door’);
!
t...
DI as Pattern
function Car(wheel, engine, door) {
this.move = function() {
engine.on();
wheel.rotate();
door.open();
}
}
The problem
function main() {
var fuel = new Fuel();
var electricity = new Electricity();
var engine = new Engine(fuel);
v...
The problem
function main() {
var fuel = new Fuel();
var electricity = new Electricity();
var engine = new Engine(fuel);
v...
The problem
function main() {
var fuel = new Fuel();
var electricity = new Electricity();
var engine = new Engine(fuel);
v...
The problem
function main() {
var fuel = new Fuel();
var electricity = new Electricity();
var engine = new Engine(fuel);
v...
DI as framework
function main() {
var injector = new Injector(….);
var car = injector.get(Car);
car.move();
}
DI as framework
function main() {
var injector = new Injector(….);
var car = injector.get(Car);
car.move();
}
Car.$inject ...
DI as framework
function main() {
var injector = new Injector(….);
var car = injector.get(Car);
car.move();
}
Car.$inject ...
Angular testability
is super-heroic!
but…
“you still have to do the right thing.”
- Angular Doc
Testability
1. Don’t use new
2. Don’t use globals
The Angular
Way
Solid structured
code
Testing components
Controller
function RocketCtrl($scope) {
$scope.maxFuel = 100;
$scope.finalCheck = function() {
if ($scope.currentFuel < $s...
Controller
function RocketCtrl($scope) {
$scope.maxFuel = 100;
$scope.finalCheck = function() {
if ($scope.currentFuel < $s...
var $scope = {};
var rc = $controller(
'RocketCtrl',
{ $scope: $scope }
);
!
$scope.currentFuel = 80;
$scope.finalCheck();
...
Directive
app.directive('rocketLaunchPad', function () {
return {
restrict: 'AE',
replace: true,
template:
‘<rocket-launch...
Directive Test
it(‘Check launchpad was installed', function() {
var element = $compile(“<rocket-launch-pad></
rocket-launc...
Tools
Karma
Protractor
Test Runner
Karma
Run tests against real browsers
Karma
Run tests against real browsers
Unit tests
Config file
> karma init
Config file
> karma init
- frameworks: [‘jasmine’]
Config file
> karma init
- frameworks: [‘jasmine’]
- autoWatch: true
Config file
> karma init
- frameworks: [‘jasmine’]
- files: [
‘../tests/controllerSpec.js’
],
- autoWatch: true
Config file
> karma init
- frameworks: [‘jasmine’]
- files: [
‘../tests/controllerSpec.js’
],
- autoWatch: true
- browsers: [...
Using Karma
> karma start config.js
Using Karma
> karma start config.js
Protractor
E2E Angular Testing
Angular wrapper for WebDriver
Anatomy of a E2E test
describe(‘…’, function() {
it(‘…’, function() {
browser.get(‘…’);
element(by.model(‘…’)).sendKeys(.....
Global Variables
describe(‘…’, function() {
it(‘…’, function() {
browser.get(‘…’);
element(by.model(‘…’)).sendKeys(..);
!
...
Global Variables
describe(‘…’, function() {
it(‘…’, function() {
browser.get(‘…’);
element(by.model(‘…’)).sendKeys(..);
!
...
Page Objects
Protractor provides
Page Objects
Protractor provides
Debugging with superpowers
Page Objects
Protractor provides
Debugging with superpowers
Angular-specific functions
Final Thoughts
Jacopo Nardiello
Twitter: @jnardiello
Questions?
Ultimate Introduction To AngularJS
Ultimate Introduction To AngularJS
Upcoming SlideShare
Loading in …5
×

Ultimate Introduction To AngularJS

827 views

Published on

The ultimate introduction to AngularJS with an overview on testing

0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
827
On SlideShare
0
From Embeds
0
Number of Embeds
19
Actions
Shares
0
Downloads
26
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Ultimate Introduction To AngularJS

  1. 1. The Ultimate Introduction to AngularJS
  2. 2. Jacopo Nardiello Padawan Programmer Twitter: @jnardiello
  3. 3. Practicing the force at
  4. 4. What Angular is NOT
  5. 5. “AngularJS is not jQuery” What Angular is NOT
  6. 6. Framework != Library
  7. 7. “A framework embodies some abstract design, with more behavior built in.” ! - M. Fowler
  8. 8. MVC MVVMvs
  9. 9. What is Angular Superheroic JavaScript MVW Framework
  10. 10. What is Angular Superheroic JavaScript MVW Framework Model
  11. 11. What is Angular Superheroic JavaScript MVW Framework View Model
  12. 12. What is Angular Superheroic JavaScript MVW Framework View Model Whatever (works for you)
  13. 13. Zen of Angular
  14. 14. #1 “It is a very good idea to decouple DOM manipulation from app logic.”
  15. 15. #2 “It is a really, really good idea to regard app testing as equal in importance to app writing”
  16. 16. #3 “It is an excellent idea to decouple the client side of an app from the server side”
  17. 17. Elements of an Angular App
  18. 18. Bootstrapping an App <body ng-app=“car">
  19. 19. JS bootstrap code angular.module('car', [ 'car.service', 'car.directive', ‘car.controller’ ])
  20. 20. JS bootstrap code angular.module('car', [ 'car.service', 'car.directive', ‘car.controller’ ])
  21. 21. JS bootstrap code angular.module('car', [ 'car.service', 'car.directive', ‘car.controller’ ])
  22. 22. JS bootstrap code angular.module('car', [ 'car.service', 'car.directive', ‘car.controller’ ])
  23. 23. Angular is modular angular.module('car.service', […]) angular.module(‘car.directives', […])
  24. 24. Extending the DOM Angular extends DOM behavior using Directives
  25. 25. Directives angular.module('greetApp', []) .directive(‘greetMe’, function() { return { template: ‘<h1>Hello</h1>’ } })
  26. 26. angular.module('greetApp', []) .directive(‘greetMe’, function() { return { template: ‘<h1>Hello</h1>’ } }) Directives
  27. 27. js html <div greet-me></div> angular.module('greetApp', []) .directive(‘greetMe’, function() { return { template: ‘<h1>Hello</h1>’ } }) Directives
  28. 28. 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); } }]);
  29. 29. 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); } }]);
  30. 30. 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); } }]);
  31. 31. 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></..>
  32. 32. Controllers “A Controller is a JavaScript constructor function that is used to augment the Angular Scope”
  33. 33. Controllers “A Controller is a JavaScript constructor function that is used to augment the Angular Scope”
  34. 34. A step back: Scopes Scope ~ Model ~ Current state
  35. 35. A step back: Scopes Scope ~ Model ~ Current state Scopes are objects organized hierarchically, aimed to mimic the DOM structure
  36. 36. 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
  37. 37. A step back: Scopes
  38. 38. Controllers var myApp = angular.module('myApp',[]); ! myApp.controller('GreetingController', [ '$scope', function($scope) { $scope.greeting = 'Hola!'; }]); js
  39. 39. Controllers var myApp = angular.module('myApp',[]); ! myApp.controller('GreetingController', [ '$scope', function($scope) { $scope.greeting = 'Hola!'; }]); <div ng-controller="GreetingController"> js html
  40. 40. Angular automagically keeps in sync the model inside controllers with views Ultimate Data Binding
  41. 41. myApp.controller('GreetingController', [ '$scope', function($scope) { $scope.greeting = 'Hola!'; }]); <div ng-controller="GreetingController"> {{ greeting }} </div> Ultimate Data Binding js html
  42. 42. Behavior everywhere (and shared resources) What if you want to declare a class, an object or a function and have it available everywhere?
  43. 43. Behavior everywhere (and shared resources) Factories
  44. 44. Behavior everywhere (and shared resources) Factories Services
  45. 45. Factory Example .factory(‘addOne', function($window) { var sum = 0 return function(sum) { sum++ $window.alert(sum) } })
  46. 46. .factory(‘addOne', function($window) { var sum = 0 return function(sum) { sum++ $window.alert(sum) } }) Factory Example
  47. 47. Behavior everywhere (and shared resources) Factories Services returned value of function instance
  48. 48. Mounting all the pieces
  49. 49. Testing Angular
  50. 50. 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/
  51. 51. Misko Hevery +
  52. 52. “Angular is written with testability in mind” - Angular Doc
  53. 53. Why is Angular easily testable?
  54. 54. Dependency Injection
  55. 55. DI As a Pattern Framework
  56. 56. DI as Pattern function Car() { var wheel = new Wheel(); var engine = Engine.getInstance(); var door = app.get(‘Door’); ! this.move = function() { engine.on(); wheel.rotate(); door.open(); } }
  57. 57. DI as Pattern function Car() { var wheel = new Wheel(); var engine = Engine.getInstance(); var door = app.get(‘Door’); ! this.move = function() { engine.on(); wheel.rotate(); door.open(); } }
  58. 58. DI as Pattern function Car(wheel, engine, door) { this.move = function() { engine.on(); wheel.rotate(); door.open(); } }
  59. 59. The problem function 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(); }
  60. 60. The problem function 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(); }
  61. 61. The problem function 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(); }
  62. 62. The problem function 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(); }
  63. 63. DI as framework function main() { var injector = new Injector(….); var car = injector.get(Car); car.move(); }
  64. 64. DI as framework function 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() { … } }
  65. 65. DI as framework function 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() { … } }
  66. 66. Angular testability is super-heroic! but…
  67. 67. “you still have to do the right thing.” - Angular Doc
  68. 68. Testability 1. Don’t use new 2. Don’t use globals
  69. 69. The Angular Way
  70. 70. Solid structured code
  71. 71. Testing components
  72. 72. Controller function RocketCtrl($scope) { $scope.maxFuel = 100; $scope.finalCheck = function() { if ($scope.currentFuel < $scope.maxFuel) { $scope.check = ‘ko’; } else { $scope.check = 'ok'; } }; }
  73. 73. Controller function RocketCtrl($scope) { $scope.maxFuel = 100; $scope.finalCheck = function() { if ($scope.currentFuel < $scope.maxFuel) { $scope.check = ‘ko’; } else { $scope.check = 'ok'; } }; }
  74. 74. var $scope = {}; var rc = $controller( 'RocketCtrl', { $scope: $scope } ); ! $scope.currentFuel = 80; $scope.finalCheck(); expect($scope.check).toEqual('ko'); Controller Test
  75. 75. Directive app.directive('rocketLaunchPad', function () { return { restrict: 'AE', replace: true, template: ‘<rocket-launch-pad> Rocket here <rocket-launch-pad>’ }; });
  76. 76. Directive Test it(‘Check launchpad was installed', function() { var element = $compile(“<rocket-launch-pad></ rocket-launch-pad>”)($rootScope); ! expect(element.html()).toContain("Rocket here"); });
  77. 77. Tools
  78. 78. Karma Protractor
  79. 79. Test Runner
  80. 80. Karma Run tests against real browsers
  81. 81. Karma Run tests against real browsers Unit tests
  82. 82. Config file > karma init
  83. 83. Config file > karma init - frameworks: [‘jasmine’]
  84. 84. Config file > karma init - frameworks: [‘jasmine’] - autoWatch: true
  85. 85. Config file > karma init - frameworks: [‘jasmine’] - files: [ ‘../tests/controllerSpec.js’ ], - autoWatch: true
  86. 86. Config file > karma init - frameworks: [‘jasmine’] - files: [ ‘../tests/controllerSpec.js’ ], - autoWatch: true - browsers: ['Chrome']
  87. 87. Using Karma > karma start config.js
  88. 88. Using Karma > karma start config.js
  89. 89. Protractor E2E Angular Testing Angular wrapper for WebDriver
  90. 90. Anatomy of a E2E test describe(‘…’, function() { it(‘…’, function() { browser.get(‘…’); element(by.model(‘…’)).sendKeys(..); ! var calculate = element(by.binding(‘…’)); ! expect(some.method()).toEqual(..); }); });
  91. 91. Global Variables describe(‘…’, function() { it(‘…’, function() { browser.get(‘…’); element(by.model(‘…’)).sendKeys(..); ! var calculate = element(by.binding(‘…’)); ! expect(some.method()).toEqual(..); }); });
  92. 92. Global Variables describe(‘…’, function() { it(‘…’, function() { browser.get(‘…’); element(by.model(‘…’)).sendKeys(..); ! var calculate = element(by.binding(‘…’)); ! expect(some.method()).toEqual(..); }); }); Super-Happy Panda!
  93. 93. Page Objects Protractor provides
  94. 94. Page Objects Protractor provides Debugging with superpowers
  95. 95. Page Objects Protractor provides Debugging with superpowers Angular-specific functions
  96. 96. Final Thoughts
  97. 97. Jacopo Nardiello Twitter: @jnardiello Questions?

×