Top 10 Mistakes AngularJS Developers Make Mark Meyer @nuclearghost
About Me Software Engineer at Sharethrough Developing on AngularJS since 1.1.5 (triangle-squarification) Built ~40k line AngularJS app and many much smaller AngularJS apps
What’s the point? AngularJS === Awesome Easy to Start Learning Curve Eventually Ramps up My Experiences from building a large application
The Mistakes 1. MVC Directory Structure 2. Modules 3. 4. 5. 6. Batarang 7. Too Many Watchers 8. Scoping $scope’s 9. Manual Testing Dependency Injection Controllers Bloat Services v Factory 10. Using jQuery
Dependency Injection Great Design Pattern for Testing and Parallelizing Development Not the prettiest in AngularJS var app = angular.module('app',[]); app.controller('MainCtrl', function($scope, $timeout){ $timeout(function(){ console.log($scope); }, 1000); });
Array Style + Safe for minification - Extra in-line code app.controller('MainCtrl', ['$scope', '$timeout', function($scope, $timeout){ $timeout(function(){ console.log($scope); }, 1000); }]);
$inject Property attached to controller functions Not as convenient for in-lining Potentially cleaner without duplicate names at declaration var MainCtrl = function($scope, $timeout){ $timeout(function(){ console.log($scope); }, 1000); }; MainCtrl.$inject = ['$scope', ‘$timeout']; //or MainCtrl[‘$inject’] app.controller('MainCtrl', MainCtrl);
ng-annotate Automatically add array style notations Integrate into build process before minification Can be easily integrated with Grunt, Gulp, Browserify, Rails Assets Pipeline, and more https://github.com/olov/ng-annotate
Controller Bloat Limit Controllers to bartering between view and data model Data model should live in provider (service, factory, etc.) Controllers should have view-model for data binding
Controller Bloat Example deadbolt by Ed Carter Chrome extension for hashing passphrase to secure password Very clean, readable code Controllers get a little lengthy handling all the user events https://github.com/bittenbytailfly/deadbolt-password- generator-chrome-extension/ blob/master/extension/js/control lers.js
Service v Factory Provider, Factory, Service, Value, Constant All based on Provider All singletons Definitely over complicated Read the docs: https://docs.angularjs.org/guide/providers
Value Often used for storing primitives, e.g. key string values var myApp = angular.module('myApp', []); myApp.value('clientId', 'a12345654321x'); myApp.controller('DemoController', ['clientId', function DemoController(clientId) { this.clientId = clientId; }]);
Constant Values available at config time and run time Every AngularJS app has config phase, then run phase myApp.constant('planetName', 'Greasy Giant');
Service Returns new’d instance of object returned in service Cannot create primitives app.service('helloWorldService', function(){ this.hello = function() { return "Hello World"; }; }); Service'. We regret this and know that we'll be somehow punished for our misdeed. It's like we named one of our
Factory Can have dependencies Can return primitives or functions myApp.factory('apiToken', ['clientId', function apiTokenFactory(clientId) { var encrypt = function(data1, data2) { // NSA-proof encryption algorithm: return (data1 + ':' + data2).toUpperCase(); }; var secret = window.localStorage.getItem('myApp.secret'); var apiToken = encrypt(clientId, secret); return apiToken; }]);
Provider Closest to the metal Must implement $get method Available during config phase
Provider Example myApp.provider('unicornLauncher', function UnicornLauncherProvider() { var useTinfoilShielding = false; this.useTinfoilShielding = function(value) { useTinfoilShielding = !!value; }; this.$get = ["apiToken", function unicornLauncherFactory(apiToken) { return new UnicornLauncher(apiToken, useTinfoilShielding); }]; }); myApp.config(["unicornLauncherProvider", function(unicornLauncherProvider) { unicornLauncherProvider.useTinfoilShielding(true); }]);
Provider Family Conclusion
The Mistakes 1. MVC Directory Structure 2. Modules 3. 4. 5. 6. Batarang 7. Too Many Watchers 8. Scoping $scope’s 9. Manual Testing Dependency Injection Controllers Bloat Services v Factory 10. Using jQuery
11. Memory Leaks Controllers and Directives should subscribe to: $scope.$on('$destroy', …) Remove handlers Clean up resources which won’t be garbage collected automatically
MVC Directory Structure templates/ _login.html _feed.html app/ app.js controllers/ LoginController.js FeedController.js directives/ FeedEntryDirective.js services/ LoginService.js FeedService.js filters/ CapatalizeFilter.js app/ app.js Feed/ _feed.html FeedController.js FeedEntryDirective.js FeedService.js Login/ _login.html LoginController.js LoginService.js Shared/ CapatalizeFilter.js
Modules Group code into bundles which are independent Directory structure should follow module design Configure routes per module Each module manages its own dependencies
Batarang Still under active-isn development Check out ng-inspector: http://ng-inspector.org/
Watchers If something doesn’t change, don’t watch it Bindonce directive is your friend https://github.com/Pasvaz/bindonce
Scoping $scopes Learn prototypical inheritance in javascript http://www.airpair.com/javascript/workshops/javascript-prototypal-inheritance Don’t stress too much 2.0 is coming
Testing Come back tomorrow http://www.airpair.com/angularjs/ workshops/unit-testing-angularjs
Further Reading Angular Best Practices: https://github.com/angular/angular.js/wiki/Best- Practices Officical App Structure Recommendation: https://docs.google.com/document/d/1XXMvReO8- Awi1EZXAXS4PzDzdNvV6pGcuaF4Q9821Es/pub
Angular 2.0 is coming! Major changes in the pipeline Goodbye Controllers, $scope, angular.module, jqLite Rob Eisenberg goes in depth: http://eisenbergeffect.bluespire.com/all-about- angular-2-0/ Igor Minar and Tobias Bosch overview: https://docs.google.com/presentation/d/1XQP0_NTzCUcFweauLlkZpbbh NVYbYy156oD--KLmXsk/edit#slide=id.g498335282_0112
Wrap Up Reach me on twitter: @nuclearghost Want individualized help?: http://airpair.me/NuclearGhost Thanks for your time!

Top 10 Mistakes AngularJS Developers Make

  • 1.
    Top 10 MistakesAngularJS Developers Make Mark Meyer @nuclearghost
  • 2.
    About Me SoftwareEngineer at Sharethrough Developing on AngularJS since 1.1.5 (triangle-squarification) Built ~40k line AngularJS app and many much smaller AngularJS apps
  • 3.
    What’s the point? AngularJS === Awesome Easy to Start Learning Curve Eventually Ramps up My Experiences from building a large application
  • 4.
    The Mistakes 1.MVC Directory Structure 2. Modules 3. 4. 5. 6. Batarang 7. Too Many Watchers 8. Scoping $scope’s 9. Manual Testing Dependency Injection Controllers Bloat Services v Factory 10. Using jQuery
  • 5.
    Dependency Injection GreatDesign Pattern for Testing and Parallelizing Development Not the prettiest in AngularJS var app = angular.module('app',[]); app.controller('MainCtrl', function($scope, $timeout){ $timeout(function(){ console.log($scope); }, 1000); });
  • 6.
    Array Style +Safe for minification - Extra in-line code app.controller('MainCtrl', ['$scope', '$timeout', function($scope, $timeout){ $timeout(function(){ console.log($scope); }, 1000); }]);
  • 7.
    $inject Property attachedto controller functions Not as convenient for in-lining Potentially cleaner without duplicate names at declaration var MainCtrl = function($scope, $timeout){ $timeout(function(){ console.log($scope); }, 1000); }; MainCtrl.$inject = ['$scope', ‘$timeout']; //or MainCtrl[‘$inject’] app.controller('MainCtrl', MainCtrl);
  • 8.
    ng-annotate Automatically addarray style notations Integrate into build process before minification Can be easily integrated with Grunt, Gulp, Browserify, Rails Assets Pipeline, and more https://github.com/olov/ng-annotate
  • 9.
    Controller Bloat LimitControllers to bartering between view and data model Data model should live in provider (service, factory, etc.) Controllers should have view-model for data binding
  • 10.
    Controller Bloat Example deadbolt by Ed Carter Chrome extension for hashing passphrase to secure password Very clean, readable code Controllers get a little lengthy handling all the user events https://github.com/bittenbytailfly/deadbolt-password- generator-chrome-extension/ blob/master/extension/js/control lers.js
  • 11.
    Service v Factory Provider, Factory, Service, Value, Constant All based on Provider All singletons Definitely over complicated Read the docs: https://docs.angularjs.org/guide/providers
  • 12.
    Value Often usedfor storing primitives, e.g. key string values var myApp = angular.module('myApp', []); myApp.value('clientId', 'a12345654321x'); myApp.controller('DemoController', ['clientId', function DemoController(clientId) { this.clientId = clientId; }]);
  • 13.
    Constant Values availableat config time and run time Every AngularJS app has config phase, then run phase myApp.constant('planetName', 'Greasy Giant');
  • 14.
    Service Returns new’dinstance of object returned in service Cannot create primitives app.service('helloWorldService', function(){ this.hello = function() { return "Hello World"; }; }); Service'. We regret this and know that we'll be somehow punished for our misdeed. It's like we named one of our
  • 15.
    Factory Can havedependencies Can return primitives or functions myApp.factory('apiToken', ['clientId', function apiTokenFactory(clientId) { var encrypt = function(data1, data2) { // NSA-proof encryption algorithm: return (data1 + ':' + data2).toUpperCase(); }; var secret = window.localStorage.getItem('myApp.secret'); var apiToken = encrypt(clientId, secret); return apiToken; }]);
  • 16.
    Provider Closest tothe metal Must implement $get method Available during config phase
  • 17.
    Provider Example myApp.provider('unicornLauncher',function UnicornLauncherProvider() { var useTinfoilShielding = false; this.useTinfoilShielding = function(value) { useTinfoilShielding = !!value; }; this.$get = ["apiToken", function unicornLauncherFactory(apiToken) { return new UnicornLauncher(apiToken, useTinfoilShielding); }]; }); myApp.config(["unicornLauncherProvider", function(unicornLauncherProvider) { unicornLauncherProvider.useTinfoilShielding(true); }]);
  • 18.
  • 19.
    The Mistakes 1.MVC Directory Structure 2. Modules 3. 4. 5. 6. Batarang 7. Too Many Watchers 8. Scoping $scope’s 9. Manual Testing Dependency Injection Controllers Bloat Services v Factory 10. Using jQuery
  • 20.
    11. Memory Leaks Controllers and Directives should subscribe to: $scope.$on('$destroy', …) Remove handlers Clean up resources which won’t be garbage collected automatically
  • 21.
    MVC Directory Structure templates/ _login.html _feed.html app/ app.js controllers/ LoginController.js FeedController.js directives/ FeedEntryDirective.js services/ LoginService.js FeedService.js filters/ CapatalizeFilter.js app/ app.js Feed/ _feed.html FeedController.js FeedEntryDirective.js FeedService.js Login/ _login.html LoginController.js LoginService.js Shared/ CapatalizeFilter.js
  • 22.
    Modules Group codeinto bundles which are independent Directory structure should follow module design Configure routes per module Each module manages its own dependencies
  • 23.
    Batarang Still underactive-isn development Check out ng-inspector: http://ng-inspector.org/
  • 24.
    Watchers If somethingdoesn’t change, don’t watch it Bindonce directive is your friend https://github.com/Pasvaz/bindonce
  • 25.
    Scoping $scopes Learnprototypical inheritance in javascript http://www.airpair.com/javascript/workshops/javascript-prototypal-inheritance Don’t stress too much 2.0 is coming
  • 26.
    Testing Come backtomorrow http://www.airpair.com/angularjs/ workshops/unit-testing-angularjs
  • 27.
    Further Reading AngularBest Practices: https://github.com/angular/angular.js/wiki/Best- Practices Officical App Structure Recommendation: https://docs.google.com/document/d/1XXMvReO8- Awi1EZXAXS4PzDzdNvV6pGcuaF4Q9821Es/pub
  • 28.
    Angular 2.0 iscoming! Major changes in the pipeline Goodbye Controllers, $scope, angular.module, jqLite Rob Eisenberg goes in depth: http://eisenbergeffect.bluespire.com/all-about- angular-2-0/ Igor Minar and Tobias Bosch overview: https://docs.google.com/presentation/d/1XQP0_NTzCUcFweauLlkZpbbh NVYbYy156oD--KLmXsk/edit#slide=id.g498335282_0112
  • 29.
    Wrap Up Reachme on twitter: @nuclearghost Want individualized help?: http://airpair.me/NuclearGhost Thanks for your time!