AngularJS in practice Eugene Fidelin © 2015 VNU Vacature Media Image by redbubble.com
AngularJS fundamentals Let me show you some pictures ... Core objects and concepts
Module The highest-level Angular object. Modules are how Angular packages its code. An Angular app as specified by the ng-app directive always corresponds to a module. Other objects are always created as children of modules. http://paislee.io/a-conceptual-introduction-to-angularjs Directive Filter
Config/Routes Basically a container for app setup. Within config it's typical to see routes configured. Routing is a pairing a view with a controller. http://paislee.io/a-conceptual-introduction-to-angularjs Directive Filter
Controller Manages a special object called a scope that is accessible by the view that knows about that controller. The controller is the gateway between the information that the view sees, and the logic that creates and works on that information. http://paislee.io/a-conceptual-introduction-to-angularjs Directive Filter
Factory/Service/Provider Places where data processing should happen. Each one is an Angular construct that simply wraps a different JavaScript approach to creating objects. With factory any other construct could be created. http://paislee.io/a-conceptual-introduction-to-angularjs Directive Filter
Directive The only place (besides the view) where DOM manipulations could be done. Any time you find yourself repeating chunks of HTML, or referring to DOM nodes in JavaScript code, create a directive to encapsulate the output. http://paislee.io/a-conceptual-introduction-to-angularjs Directive Filter
Filter Let you package the transformation of data in a way that's usable with the | syntax in the view. For example, the expression 1408471200898 | date runs a timestamp through the built-in Angular date filter, outputting Aug 19, 2014. http://paislee.io/a-conceptual-introduction-to-angularjs Directive Filter
View Is the Angular-flavored HTML. $scope lives between the view and controller, and Angular is making sure both ends of the app have the latest version of it. http://paislee.io/a-conceptual-introduction-to-angularjs Directive Filter
MVC interaction http://www.slideshare.net/kmstechnology/building-singlepage-web-applications-with-angularjs $scope
Two-way binding http://devgirl.org/2013/03/21/fun-with-angularjs
Dependency injection Each component explicitly defined its dependencies. Angular inject the requested dependency by the function argument names. Once requested Angular’s injector instantiates the dependency and inject it. angular.module('app', ['externalModule']); angular.module('app') .controller('MyController', function ($window, someOtherService) { // ... });
Bad practices I swear never to ... Make code more complicated, less reusable and much harder to test.
Access or modify DOM in the controller DOM should be changed only within the view (template) or directive.
Use in the controller scope variables defined in the view These variables (usually it is either form or form element) should be explicitly passed to the controller methods.
Have business logic in the view Views should have only render logic. The rest should be either in the controller, filter or directive (if you need to use more than 1 time). Expression in view should be as simple as possible.
Use jQuery If you are using jQuery to manipulate DOM - you don’t need it. Angular has angular.element methods to manipulate the DOM in the directive code. Any other functionality of jQuery has appropriate alternatives in Angular core or additional modules.
Perform HTTP requests in the controller Controller should only use the services which encapsulate HTTP requests and provides methods to use them.
Put any logic in the application module run method If you need something that is global for the whole application - create the service.
Use callbacks instead of promises Promises are much easier to maintain and test - use them. All asynchronous methods in Angular are returning promises, so you are already using them.
Use a scalar variable within an isolated scope Isolated scopes are created by multiple directives.Updates from outside scopes won't appear inside after scalar variable is changed inside. Example: http://embed.plnkr.co/qRhLfw/preview Note: using ControllerAs syntax solves the issue.
Good practices I’ll try my best to ... Just make your life easier and application more reliable
Separate the Angular and backend templates Use as less as possible Angular directives in the backend templates. ng-app and ng-controller to bootstrap Angular application and and ng-include to inject the Angular views.
Use ng-bind instead of {{}} The {{}} are much slower. ng-bind is a directive and it will only apply, when the passed value does actually change. The brackets on the other hand will be dirty checked and refreshed in every $digest, even if it's not necessary. Also, unrendered brackets are visible to the user, what required to use ng-cloak to hide them.
Use bind-once functionality Angular allows to bind the value of an expression/attribute once (will be bound when != ’undefined’). This is useful, when value won’t be changed. Place "::" before the binding to enable bind-once: <p ng-bind=’::value’> or {{ ::value }}
Use ConrollerAs syntax Controllers are more of a class based - all variables are assigned to this instead of $scope. Controllers are namespaced in the views. In details: Digging into Angular’s “Controller as” syntax app.controller('MainCtrl', function () { this.title = 'Some title'; }); <div ng-controller="MainCtrl as main"> {{ main.title }} </div>
Build tools Grunt is our task runner, let’s see what plugins are used. Help to write less code and keep it clean, automate the process.
grunt-contrib-jshint Detects errors and potential problems in JavaScript code. It is very flexible and can be easily adjusted to particular coding guidelines and the environment where the code will be executed
grunt-contrib-concat Concatenates multiple JavaScript files into one to speed up its downloading and page rendering. Also allows to wrap code in the Immediately-Invoked Function Expression (IIFE) that prevents you code from leaking into the global scope.
grunt-ng-annotate Adds and removes AngularJS dependency injection annotations. It is non-intrusive so the source code stays exactly the same otherwise. Annotations are useful because with them it is possible to minify the source code.
grunt-angular-templates Speed up the AngularJS app by automatically minifying, combining and caching HTML templates with $templateCache.
grunt-ng-constant Separates code and configuration by dynamically generating Angular constant modules from the json and yaml configuration files.
grunt-contrib-uglify Minifies and compress JavaScript files to minimize the size of files that must be downloaded and improve page performance. Note: Angular dependency injection annotations should be added before uglifying.
Testing A developer is known by the tests he writes. Angular is written with testability in mind, but it still requires that you do the right thing.
Main tools Karma is a JavaScript command line tool that can be used to spawn a web server which loads your application's source code and executes your tests. Jasmine is a behavior driven development framework for JavaScript. Provides functions to help with structuring tests, making assertions and creating stubs (spies). angular-mocks provides mocking for the tests. One of the most useful parts is $httpBackend, which allows to mock XHR requests in tests, and return sample data instead.
Unit tests Angular comes with dependency injection built-in, which makes testing much easier, because you can pass in a component's dependencies and stub or mock them as you wish. Test every controller, service or model in isolated environment by mocking all non-core dependencies (see Mocking Dependencies in AngularJS Tests)
Integration tests Protractor is an end-to-end test framework for AngularJS applications. Protractor runs tests against your application running in a real browser, interacting with it as a user would.
● Guide to AngularJS Documentation ● AngularJS wiki ● A Conceptual Introduction to AngularJS ● Sane, scalable Angular apps are tricky, but not impossible. Lessons learned from PayPal Checkout. ● Mocking Dependencies in AngularJS Tests Image by lifehack.org
Eugene Fidelin Contacts Email: eugene.fidelin@gmail.com Twitter: @EugeneFidelin Facebook: facebook.com/eugene.fidelin Github: github.com/eugef

AngularJS in practice

  • 1.
    AngularJS in practice Eugene Fidelin ©2015 VNU Vacature Media Image by redbubble.com
  • 2.
    AngularJS fundamentals Let meshow you some pictures ... Core objects and concepts
  • 3.
    Module The highest-level Angular object.Modules are how Angular packages its code. An Angular app as specified by the ng-app directive always corresponds to a module. Other objects are always created as children of modules. http://paislee.io/a-conceptual-introduction-to-angularjs Directive Filter
  • 4.
    Config/Routes Basically a containerfor app setup. Within config it's typical to see routes configured. Routing is a pairing a view with a controller. http://paislee.io/a-conceptual-introduction-to-angularjs Directive Filter
  • 5.
    Controller Manages a specialobject called a scope that is accessible by the view that knows about that controller. The controller is the gateway between the information that the view sees, and the logic that creates and works on that information. http://paislee.io/a-conceptual-introduction-to-angularjs Directive Filter
  • 6.
    Factory/Service/Provider Places where dataprocessing should happen. Each one is an Angular construct that simply wraps a different JavaScript approach to creating objects. With factory any other construct could be created. http://paislee.io/a-conceptual-introduction-to-angularjs Directive Filter
  • 7.
    Directive The only place(besides the view) where DOM manipulations could be done. Any time you find yourself repeating chunks of HTML, or referring to DOM nodes in JavaScript code, create a directive to encapsulate the output. http://paislee.io/a-conceptual-introduction-to-angularjs Directive Filter
  • 8.
    Filter Let you packagethe transformation of data in a way that's usable with the | syntax in the view. For example, the expression 1408471200898 | date runs a timestamp through the built-in Angular date filter, outputting Aug 19, 2014. http://paislee.io/a-conceptual-introduction-to-angularjs Directive Filter
  • 9.
    View Is the Angular-flavoredHTML. $scope lives between the view and controller, and Angular is making sure both ends of the app have the latest version of it. http://paislee.io/a-conceptual-introduction-to-angularjs Directive Filter
  • 10.
  • 11.
  • 12.
    Dependency injection Each componentexplicitly defined its dependencies. Angular inject the requested dependency by the function argument names. Once requested Angular’s injector instantiates the dependency and inject it. angular.module('app', ['externalModule']); angular.module('app') .controller('MyController', function ($window, someOtherService) { // ... });
  • 13.
    Bad practices Iswear never to ... Make code more complicated, less reusable and much harder to test.
  • 14.
    Access or modifyDOM in the controller DOM should be changed only within the view (template) or directive.
  • 15.
    Use in thecontroller scope variables defined in the view These variables (usually it is either form or form element) should be explicitly passed to the controller methods.
  • 16.
    Have business logicin the view Views should have only render logic. The rest should be either in the controller, filter or directive (if you need to use more than 1 time). Expression in view should be as simple as possible.
  • 17.
    Use jQuery If youare using jQuery to manipulate DOM - you don’t need it. Angular has angular.element methods to manipulate the DOM in the directive code. Any other functionality of jQuery has appropriate alternatives in Angular core or additional modules.
  • 18.
    Perform HTTP requestsin the controller Controller should only use the services which encapsulate HTTP requests and provides methods to use them.
  • 19.
    Put any logicin the application module run method If you need something that is global for the whole application - create the service.
  • 20.
    Use callbacks insteadof promises Promises are much easier to maintain and test - use them. All asynchronous methods in Angular are returning promises, so you are already using them.
  • 21.
    Use a scalarvariable within an isolated scope Isolated scopes are created by multiple directives.Updates from outside scopes won't appear inside after scalar variable is changed inside. Example: http://embed.plnkr.co/qRhLfw/preview Note: using ControllerAs syntax solves the issue.
  • 22.
    Good practices I’lltry my best to ... Just make your life easier and application more reliable
  • 23.
    Separate the Angularand backend templates Use as less as possible Angular directives in the backend templates. ng-app and ng-controller to bootstrap Angular application and and ng-include to inject the Angular views.
  • 24.
    Use ng-bind insteadof {{}} The {{}} are much slower. ng-bind is a directive and it will only apply, when the passed value does actually change. The brackets on the other hand will be dirty checked and refreshed in every $digest, even if it's not necessary. Also, unrendered brackets are visible to the user, what required to use ng-cloak to hide them.
  • 25.
    Use bind-once functionality Angularallows to bind the value of an expression/attribute once (will be bound when != ’undefined’). This is useful, when value won’t be changed. Place "::" before the binding to enable bind-once: <p ng-bind=’::value’> or {{ ::value }}
  • 26.
    Use ConrollerAs syntax Controllersare more of a class based - all variables are assigned to this instead of $scope. Controllers are namespaced in the views. In details: Digging into Angular’s “Controller as” syntax app.controller('MainCtrl', function () { this.title = 'Some title'; }); <div ng-controller="MainCtrl as main"> {{ main.title }} </div>
  • 27.
    Build tools Grunt isour task runner, let’s see what plugins are used. Help to write less code and keep it clean, automate the process.
  • 28.
    grunt-contrib-jshint Detects errors andpotential problems in JavaScript code. It is very flexible and can be easily adjusted to particular coding guidelines and the environment where the code will be executed
  • 29.
    grunt-contrib-concat Concatenates multiple JavaScriptfiles into one to speed up its downloading and page rendering. Also allows to wrap code in the Immediately-Invoked Function Expression (IIFE) that prevents you code from leaking into the global scope.
  • 30.
    grunt-ng-annotate Adds and removesAngularJS dependency injection annotations. It is non-intrusive so the source code stays exactly the same otherwise. Annotations are useful because with them it is possible to minify the source code.
  • 31.
    grunt-angular-templates Speed up theAngularJS app by automatically minifying, combining and caching HTML templates with $templateCache.
  • 32.
    grunt-ng-constant Separates code andconfiguration by dynamically generating Angular constant modules from the json and yaml configuration files.
  • 33.
    grunt-contrib-uglify Minifies and compressJavaScript files to minimize the size of files that must be downloaded and improve page performance. Note: Angular dependency injection annotations should be added before uglifying.
  • 34.
    Testing A developeris known by the tests he writes. Angular is written with testability in mind, but it still requires that you do the right thing.
  • 35.
    Main tools Karma isa JavaScript command line tool that can be used to spawn a web server which loads your application's source code and executes your tests. Jasmine is a behavior driven development framework for JavaScript. Provides functions to help with structuring tests, making assertions and creating stubs (spies). angular-mocks provides mocking for the tests. One of the most useful parts is $httpBackend, which allows to mock XHR requests in tests, and return sample data instead.
  • 36.
    Unit tests Angular comeswith dependency injection built-in, which makes testing much easier, because you can pass in a component's dependencies and stub or mock them as you wish. Test every controller, service or model in isolated environment by mocking all non-core dependencies (see Mocking Dependencies in AngularJS Tests)
  • 37.
    Integration tests Protractor isan end-to-end test framework for AngularJS applications. Protractor runs tests against your application running in a real browser, interacting with it as a user would.
  • 38.
    ● Guide toAngularJS Documentation ● AngularJS wiki ● A Conceptual Introduction to AngularJS ● Sane, scalable Angular apps are tricky, but not impossible. Lessons learned from PayPal Checkout. ● Mocking Dependencies in AngularJS Tests Image by lifehack.org
  • 39.