AngularJS Workshop JSFoo 2014 Shyam Seshadri
Most Important • WIFI Network – HasGeek-Wifi (If you can see this) – HasGeek (Otherwise) • WIFI password – geeksrus • Open http://is.gd/ajs1day • Clone the repository locally • open the folder created, and run – npm install
Introduction • Ex Googler • Author – AngularJS for O’Reilly – AngularJS Up & Running for O’Reilly • Entrepreneur • Coder / Geek
Agenda • 1 day • 4 Sessions • Beginning to App in 16 Steps • Hands on • Questions? Try & save them for end of each session
Agenda (contd…) Session 1 • Introduction & History • Basic Concepts & Terminologies •Working with Controllers • Angular Services •Working with AngularJS inbuilt services Session 2 • Creating your own services • Introduction to $http • Promises in AngularJS • Routing
Agenda (contd…) Session 3 • Introduction to Testing in AngularJS • Unit Testing in Angular • End to End testing Session 4 • Introduction to Directives • Creating your own directives • Best Practices
Requirements 1. NodeJS (http://nodejs.org) 2. Karma (npm install –g karma-cli) 3. Protractor (npm install –g protractor) 4. Webstorm (http://www.jetbrains.com/webstorm) - OPTIONAL
Github Repo http://is.gd/ajs1day
Code Along – Initial Setup Checkout: git clone https://github.com/Fundoo- Solutions/angularjs-one-day.git cd angularjs-one-day Run: npm install
Expectations • You will not be an expert at the end!! • Live, hands-on – but as much as time permits • Questions, as much as possible • Touch upon each and every part of AngularJS • Follow along as best – Jump steps if falling behind
Expectations - continued • One full app, from start to finish – Simple, Todolist – No Complex Directives – No Login / Auth flows • We will cover unit testing – But gloss over end to end tests • Try out things, break things – That’s how we learn!
Suggestions • Use Google Chrome – Faster – One of the best Web Development Tools • If something doesn’t work – Look at the console (in Development Tools) – Look for typos – Check against the next step
SESSION 1 – INTRODUCTION & BASICS
Agenda • MVC & the Web • Introducing AngularJS • Basic Concepts • Terminologies • Working with Controllers
The Changing Web Paradigm Complexity Shift
The need to manage complexity Data Retrieval Biz. Logic Authorization & Permissions Rendering Concurrent usage And so much more
While hitting faster turnaround times Feature 1 Deliver in 10 weeks Feature 2 Deliver in 2 weeks Feature 3 Deliver yesterday!!! So how can we even attempt to do this?
The need for • Structure • Modularity • Tests • Speed of Development
Before AngularJS • GWT – Do it all in Java • jQuery + JS – Each project is different • How do you test DOM manipulation? • Dependent on Engineers, not on frameworks
Introducing . • A MVC framework for the Web • No need for a new templating language – uses HTML • Two Way Databinding between View & Code • Allows Reusable HTML components – Directives • Separation of concerns • Routing, Deep Linking, History • Unit Testing framework built-in
The AngularJS MVC pattern The Model is fetched and manipulated by the controller Model gets rendered to the User as the View Model View Controller User Actions in the view are triggered in the controller
Model-V-C
A Simple Model in AngularJS Just any JSON object returned by the Server
M-View-C
Template + Scope => View Projection of the Model Can be styled independently Derives behavior from Controller
M-V-Controller
The Controller is responsible for Fetching data from the server Exposing data to view through Scope Handling User interactions like clicks Any other biz. logic
Data Binding jQuery only world • <p id=“nameTxt”></p> • $(‘#nameTxt’).text(nameVar); • nameVar.onChange(function(new Val, oldVal) { // Update #nameTxt }); • If an input field, then additional • $(‘#nameInp’).change(function() { nameVar = $(‘#nameInp).val(); }); AngularJS world • {{nameVar}} • <input ng-model=“nameVar”>
Create your own components jQuery only world AngularJS world What if we could just do this? <tabs> <tab title=“Home”>content here</tab> <tab title=“Contact”>content here</tab> </tabs> Plus the content, and the logic of Switching between the tabs, and so much more.
Routing In JS, for deep linking, we need to: • Have a state machine • Have an allotted view which changes • Manage addition and removal from history • Attach the right controller and scope with each view • Potentially load all content before displaying All of that with a simple API, as part of ngRoute
Server communication All the standards of $, plus • Caching • Configurability • Resources Define a Project as • And then call • Project.save() • Project.delete() • And more
Dependency Injection •The concept of asking for dependencies, rather than creating them •A Service / factory is responsible for creating and providing your dependencies (known as the injector) What •Testability •Separation of concerns •Declarative •Reusability Why •Everywhere in AngularJS • From Controllers to Services, from Directives to Filters Where
Dependency Injection
Testing DO IT!
Testing Unit Tests • Test the individual functions • Expected return values • Side effects • Focused, Specific • Mocks out larger system behavior Scenario Tests • End to End • Starts up a real browser • Behaves like a user • Can have a real server backing it
A Sample Unit test
Backend Requirements • The same requirements that jQuery has – Nothing! • Easier if it talks JSON – But not required • Works well with Java, as well as with Ruby on Rails • Needs a way of communicating to the server • Concept of transforming requests and responses – No JSON? No problem!
Do I need to develop my entire app in AngularJS? • Has the concept of ng-app – Denote a section of the page • Can integrate as a section in an existing app • Can run it beside an existing app – Some URLs handled by AngularJS • Can expand over time, gradually
Who’s using AngularJS? • Google (of course!) – Double Click for Advertisers – Youtube – And many more • Amazon • Netflix • ING • Lots of startups
Future Plans • Object.observable to replace dirty checking • Web components / Shadow DOM integration • Asynchronous Loading • Http, Socket, Offline, much more • Mobile first
AngularJS + Mobile • <30 kb compressed & minified • Optional ngTouch for Mobile • Plays really well with Cordova / Phonegap
So how do we start? • It all begins with the AngularJS library, and an ng-app <html ng-app> <head> <script src=“angular.min.js”></script> </head> <body> <input type=“text” ng-model=“name”> <h1>Hello {{name}}</h1> </body> </html>
SESSION 1 CODE-ALONG STARTS NOW
Github Repo http://is.gd/ajs1day
Code Along – Initial Setup Checkout: git clone https://github.com/Fundoo- Solutions/angularjs-one-day.git cd angularjs-one-day Run: npm install
Code Along Run: node server.js Open localhost:8000 Each Step Step 0 - Open localhost:8000/step0/app and so on…
At the beginning • Static HTML • Hardcoded data • No functionality
Code Along – Session 1 step1 • Hook up Angular step2 • Controllers & Data binding step3 •More controllers & using Directives step4 • Forms and validation step5 • Using AngularJS services
Step 1 - Hooking up AngularJS • In app.js, add, – angular.module(‘todoApp’, []); • In index.html, add – ng-app=“todoApp” • Try out AngularJS Expressions – {{1 + 2}} • Hiding the {{}} at load – ng-cloak
Pro-tip: Avoiding Flashing {{ }} • Use the ng-cloak class – Comes with angular.js – Add it to your own css • Use ng-bind – Skips the find and replace step
Step 2 - Introducing AngularJS Controllers • In sections/landing/landing-controller.js • Refer to existing app – angular.module(‘todoApp’) • Create controller – .controller(‘LandingCtrl’, []) – Second argument array – Save variables on this • Ng-controller – As syntax
Step 2 - Data Binding at play (Display) • {{ }} – Ng-bind alternative • Can refer to functions, variables – Try it out • Create this.firstTodo in LandingCtrl – {author: ‘Me’, title: ‘First todo’,completed: false, dueOn: ‘17/9/2014’} • Create var secondTodo in LandingCtrl – {author: ‘Me’, title: ‘Second todo’, completed: true, dueOn: ‘17/9/2014’}
The Crazy AngularJS Controller / Service code • angularModule.controller / service / factory / directive / filter – First argument is the name – Second argument an array • Last argument of array is a function • Every other argument is string with name of the dependency • Function gets params injected as variables in same order
Step 3 - More controllers & data-binding • Create an array of todos in LandingCtrl with – author – title – completed – dueOn • Reuse data from previous step
Using common AngularJS directives • Ng-repeat – Over todos • Ng-class – Based on completed – fade out to grey if completed – Create function getTodoClass in controller – Takes a todo object as argument – Returns object with class names as key, and boolean value
Step 4 - Forms and Validation • In file app/sections/create-update-todo/create-controller. js • Create a new controller (CreateCtrl) – Add self.todo, with completed false by default – Add function addTodo in it – Set self.message when triggered • Add a form name • Use ng-submit to trigger a controller function • Use ng-model on input fields • Use ng-disabled on button with formName.$invalid
Step 5 – Using core AngularJS services • Add dependency as string in controller / service / factory / directive • Add dependency in function arguments • Use it! – Show message using $window.alert – Add dependency on $window in CreateCtrl – Call $window.alert
AND BACK TO THEORY FOR A BIT
Concepts • Scopes • Directives • Services • Controllers • Filters • Partials
Terminology - Scopes • It’s the context, stupid! • Exposes model to the View • Allows event propagation • Options? – Parent / Child – Root – Isolated – None
Scope Hierarchy in our Application $rootScope LandingCtrl RepeatItem1 RepeatItem1 CreateCtrl
Terminology - Directives • Reusable Components • Covered in Session 4 • Can have a template associated • Behavior + Rendering • Tabs • Datepicker • Thumbnail Widgets
Terminology - Services • Behavior without a UI • Biz. Logic shared across the app • Application level Store! • Think – Server APIs – Caches / Resources – Factories
Terminology - Filters • Formatting HTML content • Can be chained with normal JSON objects • Date Filter • List Filter
Terminology - Controllers • Business Logic backing the Views • Usually a one to one association with a view • Always linked to a view • Exposes certain elements on the scope
Terminology - Partials • A View without a context • Combines with the scope to form the view • Can be placed inside other views to create a composite view
Useful Inbuilt Services • $http • $resource • $location • $window • $routeProvider
END OF SESSION 1
SESSION 2 – SERVICES, SERVERS & ROUTING
Agenda • Creating our own services • Intro to $http • Promises • Routing using ngRoute
What is an AngularJS Service • Initialized once • Returns function / object • Guaranteed singleton for scope of application
Creating your own AngularJS service • When should you create a service? – Repeated Functionality – State across the app – Wrapping third party functionality – Need something that can be intercepted / mocked • And how?
Code Along – Session 2 •Create TodoService •Use service across controllers step6
Creating Services • angular.factory(‘ServiceName’, [‘dep1’, ‘dep2’, function(dep1, dep2) {}]) • Function returns – A function – Or an object • What is returned is the public API
Step 6 – Creating TodoService • Create angular.factory  TodoService • Default array of todos (move from Ctrl) • Functions – query, returns array – add: takes a todo, adds it to array • LandingCtrl uses TodoService.query() • CreateCtrl uses TodoService.add()
Factory vs Service vs Provider • Factory – Function called – Object / Function returned • Service – new called on function provided – OO paradigm • Provider – Initial Config setup – Most configurable
Using services as a store • Singleton for the application • Controllers created and destroyed as needed • Singletons can be used for – API – Store • Return an object with the API • Any data in Service is available to another controller
Working with Servers • $http • ngResource • Promises
Terminology - Promises • JS is Asynchronous in Nature • Can lead to the nested nightmare • Instead, a promise is a simple API that allows you to chain asynchronous calls. • Gives you the ability to wait for multiple asynchronous calls to finish without resorting to timeouts • Common error handling!
Callback Hell var currentProfile = null, username = 'something'; fetchServerConfig(function(serverConfig) { fetchUserProfiles(serverConfig.USER_PROFILES, username, function(profiles) { currentProfile = profiles.currentProfile; }); });
Promise Chaining var currentProfile = fetchServerConfig() .then(function(serverConfig) { return fetchUserProfiles(serverConfig.USER_PROFILES, username); }).then(function(profiles) { return profiles.currentProfile; }, function(error) { // Handle errors in either fetchServerConfig or // fetchUserProfiles here });
Working with servers - Options $http • Low Level • Working directly with JSON • Always interact with the service • More control, more options • Only way to talk JSONP ngResource • High Level • Object representation of Server calls • Easier to read and write • Strict, expects server in a certain form
The core $http service • GET • POST • DELETE • PUT • JSONP
Configuring the $http request • Headers • Caching • Params • Data • Transformations
More hooks on the $http - Interceptors • Common post return hook • Recommended way of handling – Errors & 404s – Authorization
CODE-ALONG CONTINUES
Code Along – Session 3 •Fetch list of todos from server •Post form data to server for create step7
Fetching data from server • $http service • $http.get(url).then(function(response) { }, function(err) {}); • Ideally, wrap it in a TodoService for nicer API • URL - /api/todo
Posting data to server • $http.post(url, postData) – Same .then URL: /api/todo DATA: todo JSON object In TodoService add: create: function(todo) {}
Refreshing the list of todos? • Check out step7-events • Scope events • Can broadcast / listen for events using $scope
BACK TO THEORY FOR A BIT
Bookmarking in a Single Page App In JS, for deep linking, we need to: • Have a state machine • Have an allotted view which changes • Manage addition and removal from history • Attach the right controller and scope with each view • Potentially load all content before displaying
AngularJS routing • $routeProvider Service • Each route consists of – A URL Regex – A Template – A Controller – Other parameters
The ng-view • The part of the single page app that responds to URL changes • Associated with a single controller • One ng-view per app only!
Handling route parameters • Opening a list of recipes • Opening a single recipe • Declaratively declare them – ‘/todo/:id’ • Now available as – $routeParams.id • Dependency Injection!
Avoiding partial loads – resolve • An Empty UI while the server responds • Broken styling / formatting due to lack of data • Avoid it all with “resolve” • What is Resolve? – A series of promises – Guaranteed to be resolved before the view is shown – Passed in as parameters to the controller
SESSION 2 CODE-ALONG CONTINUES
Code Along – Session 2 •Templates added for routes step8 •Add routes for create, update, and all step9
Step 9 - Adding routes • Include angular-route.js • Include ngRoute as a module dependency • Angular.module().config() • $routeProvider.when(url, configObj) • configObj Possible params – templateUrl or template – controller – controllerAs – redirectTo – resolve
Step 9 – Reusing Templates • Create vs Edit • Same UI, different server calls
Step 9 – Other cool things • Redirect user after adding / updating todo • Add href links to navigate within application – Add Todo – Edit Todo – Home Page • ng-href vs href – Also, ng-src vs src
BACK TO THEORY FOR A BIT
Authorization in SPAs • Server side critical – Session cookies – Token based • Client side – Interceptors – Resolves – Cookies automatic – Tokens, extra effort
Advanced $http • Common Error Handling • Request / Response transformations • Extending $http
$http - Interceptors • Request & Response interceptors • Implement factory – Return object with • Request • requestError • Response • responseError
A Sample Response Interception .factory(‘myInt’, [‘$q’, function($q) { return { response: function(resp) { return resp; }, responseError: function(err) { if (canRecover(err)) { // Do Something } else { $q.reject(err); } } }; });
$http – Request / Response Transformations • transformRequest & transformResponse – function() – Global (config() section) or $http level • Take data as a parameter – Return response in needed format
END OF SESSION 2
SESSION 3 – TESTING
Agenda • Automated Testing – what, why • Unit testing • Scenario Testing
Why should you unit test? • You want to catch errors at the earliest possible time • You want to ensure that you don’t end up breaking older features • You don’t have a compiler to tell you when you make a typo
The 5 * 5 * 5 case The Setup • Server – 5 Flows • Client – 5 Flows • Client Input – 5 Flows Testing it • Manually – All possible permutations – 5 * 5 * 5 = 125 tests to ensure all flows are tested • Automated – Minimize smartly – 5 tests for server – 5 for client – 5 for client input – Another 5 – 10 end to end – Total 20 – 25 tests
TDD and you Test Driven Development, or TDD, is an AGILE methodology that flips the development lifecycle, by ensuring that tests are written first before the code is implemented, and that tests drive the development, and are not just used as a validation tool. The tenets of TDD are simple: • Code is written only when there is a failing test that requires the code to pass • Just the bare minimum amount of code is written to ensure that the test passes • Duplication is removed at every step • Once all tests are passing, the next failing test is added for the next required functionality.
TDD - Continued These simple rules ensure that: 1. Your code develops organically, and that every line of code written is purposeful. 2. Your code remains highly modular, cohesive and reusable (as you need to be able to test it) 3. You provide a comprehensive array of tests to prevent future breakages and bugs 4. The tests also act as specification and thus documentation for future needs and changes.
Unit Testing in AngularJS world • Jasmine (BDD Style) • Declarative • Reads like English • Testacular for running tests
The Jasmine / BDD framework describe("MyController:", function() { it("to work correctly", function() { var a = 12; var b = a; expect(a).toBe(b); expect(a).not.toBe(null); }); });
Dependency Injection in Tests • Testing your TodoService? beforeEach(inject(function(TodoService) { })); Want a $rootScope? Same way.
SESSION 3 CODE-ALONG STARTS NOW
Code Along – Initial Setup Run: sudo npm install –g karma-cli cd step10 karma start OR cd step10 ../node_modules/karma/bin/karma start OR DO IT FROM WEBSTORM
Code Along – Session 3 step10 • Left off from session 2 • Add a test for fetching todo list step11 step12 • Add a test for creating todo
Testing services • beforeEach(module(ModuleName)) • beforeEach(inject(function(dep1, dep2) {})); • Write your tests in each it block
Unit Testing controllers • Ask for $controller service • Create controller instance – Pass in context specific dependencies – Like $scope, $routeParams
Unit Testing with XHRs • Ask for $httpBackend service • $httpBackend.expectGET (or expectPOST) • Provide expected URL • .respond(responseData) • Don’t forget the $httpBackend.flush() calls • Don’t forget afterEach with – $httpBackend.verifyNoOutstandingExpectation() – $httpBackend.verifyNoOutstandingRequest()
Step 11 – Testing LandingCtrl • Create controller instance – $controller(‘LandingCtrl’) • Set expectations using $httpBackend – expectGET – respond – Set expectation before request is made • Remember, asynchronous! – When does the server respond? – flush()
Step 12 – Testing CreateCtrl • Create controller instance • Setup todo object that will be created – Where does it come from? • When is the create request triggered? – Set expectations before that – expectPOST(url, data) • What happens on success? – Check redirect
AND BACK TO THEORY FOR A BIT
End to End testing • Your unit tests pass • Your business logic looks correct • You have your routes setup • Are you done? • How do you know your application works?
Angular Protractor • AngularJS Aware – Grab the value of a binding – Understand the ng-repeat • WebDriver enabled – No need for yet another runner • Debugging capabilities – Pause / Resume at will
Reduce the burden on manual QA • Smoke Tests • Build validation tests • Run on every save? • Catch breakages faster, fix faster
Installation • npm install –g protractor • webdriver-manager update
The configuration (conf.js) // myConf.js exports.config = { seleniumAddress: 'http://localhost:4444/wd/hub', specs: ['e2eSpec.js'], jasmineNodeOpts: { showColors: true }, capabilities: { browserName: ’firefox' }, baseUrl: ‘http://localhost:8000’ }
Protractor – Writing Simple tests • Add a simple configuration – Point it to WebDriver and your tests • Write the test • Jasmine based – browser.get('http://localhost:8000'); – browser.findElements(by.repeater(’todo in landingCtrl.todos'))
Protractor – Interacting with the UI • AngularJS Aware • Element – By.binding – by.model – by.repeater • Browser.debugger() • Browser.takeScreenshot()
Running: Step by step Install Webdriver (First time only): webdriver-manager update Start Webdriver: webdriver-manager start Start Server: node server.js Start Protractor: cd test/e2e protractor conf.js
END OF SESSION 3
SESSION 4 – DIRECTIVES & BEST PRACTICES
Agenda • Directives – Concepts – Creating your own • Best Practices – Tools – Project Structure – Other Modules
Directives • Reusable UI widgets • Rendering + Behavior • DOM Manipulation needed  Directive
Ng-include • A poor man’s directive • Rendering, no behavior • Dependent on context
SESSION 4 CODE-ALONG STARTS
Code Along – Session 4 •Extract out stock repeater •Use ng-include to include rendering logic step13
Step 13 – ng-include • Extract out todo template into todo-widget. html • Include it using ng-include – Remember, ng-include expects a variable – Use single quotes inside double quotes to tell it it is a string constant
Limitations of ng-include • Expects each user to know name and path to the template • Dependent on context – Expects controller with functions to be defined – Expects variables to be defined with certain names • Not great for reusability • Hard to make self-contained
The Two Types of Directives Display Input
The Directive Life Cycle • Directive Created • Template Element Compiled – Template Level Modifications done here • Scope, Controller created • Link Function – Pre & Post linking (if children)
Understanding your options • Scope – Bindings • restrict • Template / Template URL • Transclude • Controller • Compile / link
Restrict • A  Attribute <div my-dir></div> • C  Class <div class=“my-dir”></div • E  Element <my-dir></my-dir>
Scope • False  Default, shares parent scope • True  Creates a new scope • {}  isolated scope – = binding -> Objects – @ binding -> Attributes / Interpolated Strings – & binding -> Functions
The Compile function • DOM transformations • Common to all instances of directive – Think ng-repeat – Think ng-view • No Scope yet
The Linking Function • Ability to add specific behavior – When your directive is first loaded – For future behavior, restricted to the element • Run once for each instance of your element
Directive Controllers • Controller functions for your directive • Used for cross directive communication • Use Link – When you have functionality specific to your directive • Use Controller – When you have functionality that other directives (usually child) will need to access
Transclusions • Customized content for directives – Changes from usage to usage • Think Tabs • Think Zippy / Accordions • Think Carousels
SESSION 4 CODE-ALONG CONTINUES
Code Along – Session 4 • Convert ng-include to directive step14 • Convert directive to fully contained with data passed in step15 step16 • Delete todo and reload list
Step 14 - Converting ng-include to directive • Create directive todoWidget – Use as todo-widget in HTML • Return Directive definition object – Restrict: ‘A’ – templateUrl: ‘components/todo-widget/todo-widget. html’
Step 15 - Self contained directives • Scope param – ‘=‘ binding – todo: ‘=todoData’ – Takes todo-data in HTML, saves it as $scope.todo • Link function – Gets three arguments - $scope, $element, $attrs – getTodoClass function on $scope
Step 16 – Delete todo and reload list • Add del function in todo-service – $http[“delete”](‘/api/todo’ + id); • Add button in todo-widget.html – ng-click=“deleteTodo()” • In directive – Add deleteTodo() function which calls service – Add whenDelete: ‘&’ in scope attribute – On success of service call, call $scope.whenDelete() • In LandingCtrl – Add reload function – In HTML, add when-delete=“lCtrl.reload()”
BACK TO THEORY
BEST PRACTICES, MODULES, TOOLS
10 DOS AND 10 DON’TS IN ANGULARJS
DO #1: WRITE YOUR UNIT TESTS (AND SCENARIO TESTS)
DO #2: LEVERAGE DATA BINDING
DO #3: WRAP 3RD PARTY COMPONENTS AS DIRECTIVES / SERVICES
DO #4: USE MODULES & ORGANIZE CODE BY FUNCTIONALITY
DO #5: USE TRACK BY FOR NG-REPEAT
DO #6: NAMESPACE YOUR CODE
DO #7: USE MULTIPLE LAYERS FOR SERVICES
DO #8: MINIMIZE DATA ON SCOPE / THIS
DO #9: USE THE CONTROLLER AS SYNTAX
DO #10: USE RESOLVE FOR PRE-ROUTE CHECKS & INTERCEPTORS FOR ALL OTHERS
DON’T #1: USE $ROOTSCOPE AS A STORE. DON’T USE $SCOPE TO SHARE FUNCTIONS & VARIABLES
DON’T #2: DOM MANIPULATION IN CONTROLLER
DON’T #3: OVERUSE FILTERS IN YOUR HTML
DON’T #4: PUT DATA YOU DON’T SHOW ON SCOPE / THIS
DON’T #5: MANIPULATE THE UI DIRECTLY
DON’T #6: USE GLOBAL SELECTORS IN DIRECTIVES
DON’T #7: GO OVERBOARD WITH NG-REPEATS
DON’T #8: OVERUSE SCOPE EVENTS IN YOUR APPLICATION
DON’T #9: FORGET CLEANUP IN YOUR CONTROLLERS & DIRECTIVES
DON’T #10: CREATE GIANT FILES OR FOLDERS
Other modules • Animation • Touch • Cookies • Resource • Security • Routing
BEST PRACTICES
Directory Structure • Yeoman / Angular – seed • App – images – css – Vendors (libs) – sections – components • Tests – Spec • Mimic js folder structure – E2e • Reflect app heirarchy
Modularizing your codebase • What can be reused? • What belongs in logical groups? • Group by functionality, not by type
Build Process • Grunt / Ant • Glob / Minify your code base • Load at the end of body • Cache static files – Namespace by version – Use Etags • ng-boilerplate is a great starting point
RequireJS • Good • Can be overkill – Lot of extra boilerplate • Great for lazy loading dependencies • Beneficial only if you have hundreds of files
Dependency Injection • Use it • Depend on it • Use the [] notation (more on this later) • Capture external dependencies in Services • Use Mocks to inject dependencies in tests • Look at ng-annotate if you want to be lazy
3rd party callbacks & $apply Do • Use 3rd party libraries and components • Integrate them as directives / services when possible Don’t • Forget to call $apply to let angular know when to do work
Handling Data & ACLs • Resolve – Load Data – Handle auth checks – Login or not? • Interceptors – Per request level
Flashing {{}} in HTML • Use ng-cloak • Use ng-bind instead of {{ }}
Syntax • Use module. Syntax • Use safe DI • Namespace as much as possible
Putting things on $scope • Minimize • What the view needs only! • The scope is heavy and expensive • Every item gets digested and dirty checked • Think twice, and thrice first
The $rootScope DO NOT • Use the root scope to store global state • Use the root scope as a communication mechanism • In fact, forget there is a parent $rootScope if at all possible Valid Uses: • Broadcasting and listening for events
Communicating in the App • Services • Scope  $broadcast, $emit and $on • URL Params
Attribute Directives • You can create directives that are – Attributes (like ng-show, ng-hide) – Elements (<datepicker>) – Classes (<div class=“autocomplete”>) – Comments (<!– datepicker -->) • But – Always prefer to use attributes or classes – IE compatibility issues!
Structuring Business Logic Controllers • should not reference DOM • should have view behavior – What should happen if user does X – Where do I get X from? Services • should not reference DOM (mostly) • are singletons • have logic independent of view – Do X operation PS: Do put DOM manipulation in Directives
Using the [] for DI myApp.controller(‘MyCtrl’, function($scope, $location) { }); Is the same as myApp.controller(‘MyCtrl’, [‘$scope’, ‘$location’, function($scope, $loc) { }]);
Using the [] for DI Until you compile your code! myApp.controller(‘MyCtrl’, function(a, xy) { }); Is not the same as myApp.controller(‘MyCtrl’, [‘$scope’, ‘$location’, function(a, xy) { }]); [] notation is the only way AngularJS knows which params are which!
To $ or not to $ • $ is used by AngularJS internals only – $scope – $http – $resource • Don’t use $ when you are naming your own services, controllers, etc.
USEFUL TOOLS & LIBRARIES
Batarang
Karma + Webstorm
3rd Party Components • Wijmo • KendoUI • Angular-UI • ngModules.org
Other Tools • Yeoman • Ng-Boilerplate
SO IN SUMMARY…
Feedback • shyam@befundoo.com – Feedback? – Comments? – Suggestions? • omniscient1 on Twitter • Recommend us on LinkedIn (Fundoo Solutions) if you like it

AngularJS One Day Workshop

  • 1.
    AngularJS Workshop JSFoo2014 Shyam Seshadri
  • 2.
    Most Important •WIFI Network – HasGeek-Wifi (If you can see this) – HasGeek (Otherwise) • WIFI password – geeksrus • Open http://is.gd/ajs1day • Clone the repository locally • open the folder created, and run – npm install
  • 3.
    Introduction • ExGoogler • Author – AngularJS for O’Reilly – AngularJS Up & Running for O’Reilly • Entrepreneur • Coder / Geek
  • 4.
    Agenda • 1day • 4 Sessions • Beginning to App in 16 Steps • Hands on • Questions? Try & save them for end of each session
  • 5.
    Agenda (contd…) Session1 • Introduction & History • Basic Concepts & Terminologies •Working with Controllers • Angular Services •Working with AngularJS inbuilt services Session 2 • Creating your own services • Introduction to $http • Promises in AngularJS • Routing
  • 6.
    Agenda (contd…) Session3 • Introduction to Testing in AngularJS • Unit Testing in Angular • End to End testing Session 4 • Introduction to Directives • Creating your own directives • Best Practices
  • 7.
    Requirements 1. NodeJS(http://nodejs.org) 2. Karma (npm install –g karma-cli) 3. Protractor (npm install –g protractor) 4. Webstorm (http://www.jetbrains.com/webstorm) - OPTIONAL
  • 8.
  • 10.
    Code Along –Initial Setup Checkout: git clone https://github.com/Fundoo- Solutions/angularjs-one-day.git cd angularjs-one-day Run: npm install
  • 11.
    Expectations • Youwill not be an expert at the end!! • Live, hands-on – but as much as time permits • Questions, as much as possible • Touch upon each and every part of AngularJS • Follow along as best – Jump steps if falling behind
  • 12.
    Expectations - continued • One full app, from start to finish – Simple, Todolist – No Complex Directives – No Login / Auth flows • We will cover unit testing – But gloss over end to end tests • Try out things, break things – That’s how we learn!
  • 13.
    Suggestions • UseGoogle Chrome – Faster – One of the best Web Development Tools • If something doesn’t work – Look at the console (in Development Tools) – Look for typos – Check against the next step
  • 14.
    SESSION 1 –INTRODUCTION & BASICS
  • 15.
    Agenda • MVC& the Web • Introducing AngularJS • Basic Concepts • Terminologies • Working with Controllers
  • 16.
    The Changing WebParadigm Complexity Shift
  • 17.
    The need tomanage complexity Data Retrieval Biz. Logic Authorization & Permissions Rendering Concurrent usage And so much more
  • 18.
    While hitting fasterturnaround times Feature 1 Deliver in 10 weeks Feature 2 Deliver in 2 weeks Feature 3 Deliver yesterday!!! So how can we even attempt to do this?
  • 19.
    The need for • Structure • Modularity • Tests • Speed of Development
  • 20.
    Before AngularJS •GWT – Do it all in Java • jQuery + JS – Each project is different • How do you test DOM manipulation? • Dependent on Engineers, not on frameworks
  • 21.
    Introducing . •A MVC framework for the Web • No need for a new templating language – uses HTML • Two Way Databinding between View & Code • Allows Reusable HTML components – Directives • Separation of concerns • Routing, Deep Linking, History • Unit Testing framework built-in
  • 22.
    The AngularJS MVCpattern The Model is fetched and manipulated by the controller Model gets rendered to the User as the View Model View Controller User Actions in the view are triggered in the controller
  • 23.
  • 24.
    A Simple Modelin AngularJS Just any JSON object returned by the Server
  • 25.
  • 26.
    Template + Scope=> View Projection of the Model Can be styled independently Derives behavior from Controller
  • 27.
  • 28.
    The Controller isresponsible for Fetching data from the server Exposing data to view through Scope Handling User interactions like clicks Any other biz. logic
  • 29.
    Data Binding jQueryonly world • <p id=“nameTxt”></p> • $(‘#nameTxt’).text(nameVar); • nameVar.onChange(function(new Val, oldVal) { // Update #nameTxt }); • If an input field, then additional • $(‘#nameInp’).change(function() { nameVar = $(‘#nameInp).val(); }); AngularJS world • {{nameVar}} • <input ng-model=“nameVar”>
  • 30.
    Create your owncomponents jQuery only world AngularJS world What if we could just do this? <tabs> <tab title=“Home”>content here</tab> <tab title=“Contact”>content here</tab> </tabs> Plus the content, and the logic of Switching between the tabs, and so much more.
  • 31.
    Routing In JS,for deep linking, we need to: • Have a state machine • Have an allotted view which changes • Manage addition and removal from history • Attach the right controller and scope with each view • Potentially load all content before displaying All of that with a simple API, as part of ngRoute
  • 32.
    Server communication Allthe standards of $, plus • Caching • Configurability • Resources Define a Project as • And then call • Project.save() • Project.delete() • And more
  • 33.
    Dependency Injection •Theconcept of asking for dependencies, rather than creating them •A Service / factory is responsible for creating and providing your dependencies (known as the injector) What •Testability •Separation of concerns •Declarative •Reusability Why •Everywhere in AngularJS • From Controllers to Services, from Directives to Filters Where
  • 34.
  • 35.
  • 36.
    Testing Unit Tests • Test the individual functions • Expected return values • Side effects • Focused, Specific • Mocks out larger system behavior Scenario Tests • End to End • Starts up a real browser • Behaves like a user • Can have a real server backing it
  • 37.
  • 38.
    Backend Requirements •The same requirements that jQuery has – Nothing! • Easier if it talks JSON – But not required • Works well with Java, as well as with Ruby on Rails • Needs a way of communicating to the server • Concept of transforming requests and responses – No JSON? No problem!
  • 39.
    Do I needto develop my entire app in AngularJS? • Has the concept of ng-app – Denote a section of the page • Can integrate as a section in an existing app • Can run it beside an existing app – Some URLs handled by AngularJS • Can expand over time, gradually
  • 40.
    Who’s using AngularJS? • Google (of course!) – Double Click for Advertisers – Youtube – And many more • Amazon • Netflix • ING • Lots of startups
  • 41.
    Future Plans •Object.observable to replace dirty checking • Web components / Shadow DOM integration • Asynchronous Loading • Http, Socket, Offline, much more • Mobile first
  • 42.
    AngularJS + Mobile • <30 kb compressed & minified • Optional ngTouch for Mobile • Plays really well with Cordova / Phonegap
  • 43.
    So how dowe start? • It all begins with the AngularJS library, and an ng-app <html ng-app> <head> <script src=“angular.min.js”></script> </head> <body> <input type=“text” ng-model=“name”> <h1>Hello {{name}}</h1> </body> </html>
  • 44.
  • 45.
  • 46.
    Code Along –Initial Setup Checkout: git clone https://github.com/Fundoo- Solutions/angularjs-one-day.git cd angularjs-one-day Run: npm install
  • 47.
    Code Along Run: node server.js Open localhost:8000 Each Step Step 0 - Open localhost:8000/step0/app and so on…
  • 48.
    At the beginning • Static HTML • Hardcoded data • No functionality
  • 49.
    Code Along –Session 1 step1 • Hook up Angular step2 • Controllers & Data binding step3 •More controllers & using Directives step4 • Forms and validation step5 • Using AngularJS services
  • 50.
    Step 1 -Hooking up AngularJS • In app.js, add, – angular.module(‘todoApp’, []); • In index.html, add – ng-app=“todoApp” • Try out AngularJS Expressions – {{1 + 2}} • Hiding the {{}} at load – ng-cloak
  • 51.
    Pro-tip: Avoiding Flashing{{ }} • Use the ng-cloak class – Comes with angular.js – Add it to your own css • Use ng-bind – Skips the find and replace step
  • 52.
    Step 2 -Introducing AngularJS Controllers • In sections/landing/landing-controller.js • Refer to existing app – angular.module(‘todoApp’) • Create controller – .controller(‘LandingCtrl’, []) – Second argument array – Save variables on this • Ng-controller – As syntax
  • 53.
    Step 2 -Data Binding at play (Display) • {{ }} – Ng-bind alternative • Can refer to functions, variables – Try it out • Create this.firstTodo in LandingCtrl – {author: ‘Me’, title: ‘First todo’,completed: false, dueOn: ‘17/9/2014’} • Create var secondTodo in LandingCtrl – {author: ‘Me’, title: ‘Second todo’, completed: true, dueOn: ‘17/9/2014’}
  • 54.
    The Crazy AngularJSController / Service code • angularModule.controller / service / factory / directive / filter – First argument is the name – Second argument an array • Last argument of array is a function • Every other argument is string with name of the dependency • Function gets params injected as variables in same order
  • 55.
    Step 3 -More controllers & data-binding • Create an array of todos in LandingCtrl with – author – title – completed – dueOn • Reuse data from previous step
  • 56.
    Using common AngularJSdirectives • Ng-repeat – Over todos • Ng-class – Based on completed – fade out to grey if completed – Create function getTodoClass in controller – Takes a todo object as argument – Returns object with class names as key, and boolean value
  • 57.
    Step 4 -Forms and Validation • In file app/sections/create-update-todo/create-controller. js • Create a new controller (CreateCtrl) – Add self.todo, with completed false by default – Add function addTodo in it – Set self.message when triggered • Add a form name • Use ng-submit to trigger a controller function • Use ng-model on input fields • Use ng-disabled on button with formName.$invalid
  • 58.
    Step 5 –Using core AngularJS services • Add dependency as string in controller / service / factory / directive • Add dependency in function arguments • Use it! – Show message using $window.alert – Add dependency on $window in CreateCtrl – Call $window.alert
  • 59.
    AND BACK TOTHEORY FOR A BIT
  • 60.
    Concepts • Scopes • Directives • Services • Controllers • Filters • Partials
  • 61.
    Terminology - Scopes • It’s the context, stupid! • Exposes model to the View • Allows event propagation • Options? – Parent / Child – Root – Isolated – None
  • 62.
    Scope Hierarchy inour Application $rootScope LandingCtrl RepeatItem1 RepeatItem1 CreateCtrl
  • 63.
    Terminology - Directives • Reusable Components • Covered in Session 4 • Can have a template associated • Behavior + Rendering • Tabs • Datepicker • Thumbnail Widgets
  • 64.
    Terminology - Services • Behavior without a UI • Biz. Logic shared across the app • Application level Store! • Think – Server APIs – Caches / Resources – Factories
  • 65.
    Terminology - Filters • Formatting HTML content • Can be chained with normal JSON objects • Date Filter • List Filter
  • 66.
    Terminology - Controllers • Business Logic backing the Views • Usually a one to one association with a view • Always linked to a view • Exposes certain elements on the scope
  • 67.
    Terminology - Partials • A View without a context • Combines with the scope to form the view • Can be placed inside other views to create a composite view
  • 68.
    Useful Inbuilt Services • $http • $resource • $location • $window • $routeProvider
  • 69.
  • 70.
    SESSION 2 –SERVICES, SERVERS & ROUTING
  • 71.
    Agenda • Creatingour own services • Intro to $http • Promises • Routing using ngRoute
  • 72.
    What is anAngularJS Service • Initialized once • Returns function / object • Guaranteed singleton for scope of application
  • 73.
    Creating your ownAngularJS service • When should you create a service? – Repeated Functionality – State across the app – Wrapping third party functionality – Need something that can be intercepted / mocked • And how?
  • 74.
    Code Along –Session 2 •Create TodoService •Use service across controllers step6
  • 75.
    Creating Services •angular.factory(‘ServiceName’, [‘dep1’, ‘dep2’, function(dep1, dep2) {}]) • Function returns – A function – Or an object • What is returned is the public API
  • 76.
    Step 6 –Creating TodoService • Create angular.factory  TodoService • Default array of todos (move from Ctrl) • Functions – query, returns array – add: takes a todo, adds it to array • LandingCtrl uses TodoService.query() • CreateCtrl uses TodoService.add()
  • 77.
    Factory vs Servicevs Provider • Factory – Function called – Object / Function returned • Service – new called on function provided – OO paradigm • Provider – Initial Config setup – Most configurable
  • 78.
    Using services asa store • Singleton for the application • Controllers created and destroyed as needed • Singletons can be used for – API – Store • Return an object with the API • Any data in Service is available to another controller
  • 79.
    Working with Servers • $http • ngResource • Promises
  • 80.
    Terminology - Promises • JS is Asynchronous in Nature • Can lead to the nested nightmare • Instead, a promise is a simple API that allows you to chain asynchronous calls. • Gives you the ability to wait for multiple asynchronous calls to finish without resorting to timeouts • Common error handling!
  • 81.
    Callback Hell varcurrentProfile = null, username = 'something'; fetchServerConfig(function(serverConfig) { fetchUserProfiles(serverConfig.USER_PROFILES, username, function(profiles) { currentProfile = profiles.currentProfile; }); });
  • 82.
    Promise Chaining varcurrentProfile = fetchServerConfig() .then(function(serverConfig) { return fetchUserProfiles(serverConfig.USER_PROFILES, username); }).then(function(profiles) { return profiles.currentProfile; }, function(error) { // Handle errors in either fetchServerConfig or // fetchUserProfiles here });
  • 83.
    Working with servers- Options $http • Low Level • Working directly with JSON • Always interact with the service • More control, more options • Only way to talk JSONP ngResource • High Level • Object representation of Server calls • Easier to read and write • Strict, expects server in a certain form
  • 84.
    The core $httpservice • GET • POST • DELETE • PUT • JSONP
  • 85.
    Configuring the $httprequest • Headers • Caching • Params • Data • Transformations
  • 86.
    More hooks onthe $http - Interceptors • Common post return hook • Recommended way of handling – Errors & 404s – Authorization
  • 87.
  • 88.
    Code Along –Session 3 •Fetch list of todos from server •Post form data to server for create step7
  • 89.
    Fetching data fromserver • $http service • $http.get(url).then(function(response) { }, function(err) {}); • Ideally, wrap it in a TodoService for nicer API • URL - /api/todo
  • 90.
    Posting data toserver • $http.post(url, postData) – Same .then URL: /api/todo DATA: todo JSON object In TodoService add: create: function(todo) {}
  • 91.
    Refreshing the listof todos? • Check out step7-events • Scope events • Can broadcast / listen for events using $scope
  • 92.
    BACK TO THEORYFOR A BIT
  • 93.
    Bookmarking in aSingle Page App In JS, for deep linking, we need to: • Have a state machine • Have an allotted view which changes • Manage addition and removal from history • Attach the right controller and scope with each view • Potentially load all content before displaying
  • 94.
    AngularJS routing •$routeProvider Service • Each route consists of – A URL Regex – A Template – A Controller – Other parameters
  • 95.
    The ng-view •The part of the single page app that responds to URL changes • Associated with a single controller • One ng-view per app only!
  • 96.
    Handling route parameters • Opening a list of recipes • Opening a single recipe • Declaratively declare them – ‘/todo/:id’ • Now available as – $routeParams.id • Dependency Injection!
  • 97.
    Avoiding partial loads– resolve • An Empty UI while the server responds • Broken styling / formatting due to lack of data • Avoid it all with “resolve” • What is Resolve? – A series of promises – Guaranteed to be resolved before the view is shown – Passed in as parameters to the controller
  • 98.
  • 99.
    Code Along –Session 2 •Templates added for routes step8 •Add routes for create, update, and all step9
  • 100.
    Step 9 -Adding routes • Include angular-route.js • Include ngRoute as a module dependency • Angular.module().config() • $routeProvider.when(url, configObj) • configObj Possible params – templateUrl or template – controller – controllerAs – redirectTo – resolve
  • 101.
    Step 9 –Reusing Templates • Create vs Edit • Same UI, different server calls
  • 102.
    Step 9 –Other cool things • Redirect user after adding / updating todo • Add href links to navigate within application – Add Todo – Edit Todo – Home Page • ng-href vs href – Also, ng-src vs src
  • 103.
    BACK TO THEORYFOR A BIT
  • 104.
    Authorization in SPAs • Server side critical – Session cookies – Token based • Client side – Interceptors – Resolves – Cookies automatic – Tokens, extra effort
  • 105.
    Advanced $http •Common Error Handling • Request / Response transformations • Extending $http
  • 106.
    $http - Interceptors • Request & Response interceptors • Implement factory – Return object with • Request • requestError • Response • responseError
  • 107.
    A Sample ResponseInterception .factory(‘myInt’, [‘$q’, function($q) { return { response: function(resp) { return resp; }, responseError: function(err) { if (canRecover(err)) { // Do Something } else { $q.reject(err); } } }; });
  • 108.
    $http – Request/ Response Transformations • transformRequest & transformResponse – function() – Global (config() section) or $http level • Take data as a parameter – Return response in needed format
  • 109.
  • 110.
  • 111.
    Agenda • AutomatedTesting – what, why • Unit testing • Scenario Testing
  • 112.
    Why should youunit test? • You want to catch errors at the earliest possible time • You want to ensure that you don’t end up breaking older features • You don’t have a compiler to tell you when you make a typo
  • 113.
    The 5 *5 * 5 case The Setup • Server – 5 Flows • Client – 5 Flows • Client Input – 5 Flows Testing it • Manually – All possible permutations – 5 * 5 * 5 = 125 tests to ensure all flows are tested • Automated – Minimize smartly – 5 tests for server – 5 for client – 5 for client input – Another 5 – 10 end to end – Total 20 – 25 tests
  • 114.
    TDD and you Test Driven Development, or TDD, is an AGILE methodology that flips the development lifecycle, by ensuring that tests are written first before the code is implemented, and that tests drive the development, and are not just used as a validation tool. The tenets of TDD are simple: • Code is written only when there is a failing test that requires the code to pass • Just the bare minimum amount of code is written to ensure that the test passes • Duplication is removed at every step • Once all tests are passing, the next failing test is added for the next required functionality.
  • 115.
    TDD - Continued These simple rules ensure that: 1. Your code develops organically, and that every line of code written is purposeful. 2. Your code remains highly modular, cohesive and reusable (as you need to be able to test it) 3. You provide a comprehensive array of tests to prevent future breakages and bugs 4. The tests also act as specification and thus documentation for future needs and changes.
  • 116.
    Unit Testing inAngularJS world • Jasmine (BDD Style) • Declarative • Reads like English • Testacular for running tests
  • 117.
    The Jasmine /BDD framework describe("MyController:", function() { it("to work correctly", function() { var a = 12; var b = a; expect(a).toBe(b); expect(a).not.toBe(null); }); });
  • 118.
    Dependency Injection inTests • Testing your TodoService? beforeEach(inject(function(TodoService) { })); Want a $rootScope? Same way.
  • 119.
  • 120.
    Code Along –Initial Setup Run: sudo npm install –g karma-cli cd step10 karma start OR cd step10 ../node_modules/karma/bin/karma start OR DO IT FROM WEBSTORM
  • 121.
    Code Along –Session 3 step10 • Left off from session 2 • Add a test for fetching todo list step11 step12 • Add a test for creating todo
  • 122.
    Testing services •beforeEach(module(ModuleName)) • beforeEach(inject(function(dep1, dep2) {})); • Write your tests in each it block
  • 123.
    Unit Testing controllers • Ask for $controller service • Create controller instance – Pass in context specific dependencies – Like $scope, $routeParams
  • 124.
    Unit Testing withXHRs • Ask for $httpBackend service • $httpBackend.expectGET (or expectPOST) • Provide expected URL • .respond(responseData) • Don’t forget the $httpBackend.flush() calls • Don’t forget afterEach with – $httpBackend.verifyNoOutstandingExpectation() – $httpBackend.verifyNoOutstandingRequest()
  • 125.
    Step 11 –Testing LandingCtrl • Create controller instance – $controller(‘LandingCtrl’) • Set expectations using $httpBackend – expectGET – respond – Set expectation before request is made • Remember, asynchronous! – When does the server respond? – flush()
  • 126.
    Step 12 –Testing CreateCtrl • Create controller instance • Setup todo object that will be created – Where does it come from? • When is the create request triggered? – Set expectations before that – expectPOST(url, data) • What happens on success? – Check redirect
  • 127.
    AND BACK TOTHEORY FOR A BIT
  • 128.
    End to Endtesting • Your unit tests pass • Your business logic looks correct • You have your routes setup • Are you done? • How do you know your application works?
  • 129.
    Angular Protractor •AngularJS Aware – Grab the value of a binding – Understand the ng-repeat • WebDriver enabled – No need for yet another runner • Debugging capabilities – Pause / Resume at will
  • 130.
    Reduce the burdenon manual QA • Smoke Tests • Build validation tests • Run on every save? • Catch breakages faster, fix faster
  • 131.
    Installation • npminstall –g protractor • webdriver-manager update
  • 132.
    The configuration (conf.js) // myConf.js exports.config = { seleniumAddress: 'http://localhost:4444/wd/hub', specs: ['e2eSpec.js'], jasmineNodeOpts: { showColors: true }, capabilities: { browserName: ’firefox' }, baseUrl: ‘http://localhost:8000’ }
  • 133.
    Protractor – WritingSimple tests • Add a simple configuration – Point it to WebDriver and your tests • Write the test • Jasmine based – browser.get('http://localhost:8000'); – browser.findElements(by.repeater(’todo in landingCtrl.todos'))
  • 134.
    Protractor – Interactingwith the UI • AngularJS Aware • Element – By.binding – by.model – by.repeater • Browser.debugger() • Browser.takeScreenshot()
  • 135.
    Running: Step bystep Install Webdriver (First time only): webdriver-manager update Start Webdriver: webdriver-manager start Start Server: node server.js Start Protractor: cd test/e2e protractor conf.js
  • 136.
  • 137.
    SESSION 4 –DIRECTIVES & BEST PRACTICES
  • 138.
    Agenda • Directives – Concepts – Creating your own • Best Practices – Tools – Project Structure – Other Modules
  • 139.
    Directives • ReusableUI widgets • Rendering + Behavior • DOM Manipulation needed  Directive
  • 140.
    Ng-include • Apoor man’s directive • Rendering, no behavior • Dependent on context
  • 141.
  • 142.
    Code Along –Session 4 •Extract out stock repeater •Use ng-include to include rendering logic step13
  • 143.
    Step 13 –ng-include • Extract out todo template into todo-widget. html • Include it using ng-include – Remember, ng-include expects a variable – Use single quotes inside double quotes to tell it it is a string constant
  • 144.
    Limitations of ng-include • Expects each user to know name and path to the template • Dependent on context – Expects controller with functions to be defined – Expects variables to be defined with certain names • Not great for reusability • Hard to make self-contained
  • 145.
    The Two Typesof Directives Display Input
  • 146.
    The Directive LifeCycle • Directive Created • Template Element Compiled – Template Level Modifications done here • Scope, Controller created • Link Function – Pre & Post linking (if children)
  • 147.
    Understanding your options • Scope – Bindings • restrict • Template / Template URL • Transclude • Controller • Compile / link
  • 148.
    Restrict • A Attribute <div my-dir></div> • C  Class <div class=“my-dir”></div • E  Element <my-dir></my-dir>
  • 149.
    Scope • False Default, shares parent scope • True  Creates a new scope • {}  isolated scope – = binding -> Objects – @ binding -> Attributes / Interpolated Strings – & binding -> Functions
  • 150.
    The Compile function • DOM transformations • Common to all instances of directive – Think ng-repeat – Think ng-view • No Scope yet
  • 151.
    The Linking Function • Ability to add specific behavior – When your directive is first loaded – For future behavior, restricted to the element • Run once for each instance of your element
  • 152.
    Directive Controllers •Controller functions for your directive • Used for cross directive communication • Use Link – When you have functionality specific to your directive • Use Controller – When you have functionality that other directives (usually child) will need to access
  • 153.
    Transclusions • Customizedcontent for directives – Changes from usage to usage • Think Tabs • Think Zippy / Accordions • Think Carousels
  • 154.
  • 155.
    Code Along –Session 4 • Convert ng-include to directive step14 • Convert directive to fully contained with data passed in step15 step16 • Delete todo and reload list
  • 156.
    Step 14 -Converting ng-include to directive • Create directive todoWidget – Use as todo-widget in HTML • Return Directive definition object – Restrict: ‘A’ – templateUrl: ‘components/todo-widget/todo-widget. html’
  • 157.
    Step 15 -Self contained directives • Scope param – ‘=‘ binding – todo: ‘=todoData’ – Takes todo-data in HTML, saves it as $scope.todo • Link function – Gets three arguments - $scope, $element, $attrs – getTodoClass function on $scope
  • 158.
    Step 16 –Delete todo and reload list • Add del function in todo-service – $http[“delete”](‘/api/todo’ + id); • Add button in todo-widget.html – ng-click=“deleteTodo()” • In directive – Add deleteTodo() function which calls service – Add whenDelete: ‘&’ in scope attribute – On success of service call, call $scope.whenDelete() • In LandingCtrl – Add reload function – In HTML, add when-delete=“lCtrl.reload()”
  • 159.
  • 160.
  • 161.
    10 DOS AND10 DON’TS IN ANGULARJS
  • 162.
    DO #1: WRITEYOUR UNIT TESTS (AND SCENARIO TESTS)
  • 163.
    DO #2: LEVERAGEDATA BINDING
  • 164.
    DO #3: WRAP3RD PARTY COMPONENTS AS DIRECTIVES / SERVICES
  • 165.
    DO #4: USEMODULES & ORGANIZE CODE BY FUNCTIONALITY
  • 166.
    DO #5: USETRACK BY FOR NG-REPEAT
  • 167.
  • 168.
    DO #7: USEMULTIPLE LAYERS FOR SERVICES
  • 169.
    DO #8: MINIMIZEDATA ON SCOPE / THIS
  • 170.
    DO #9: USETHE CONTROLLER AS SYNTAX
  • 171.
    DO #10: USERESOLVE FOR PRE-ROUTE CHECKS & INTERCEPTORS FOR ALL OTHERS
  • 172.
    DON’T #1: USE$ROOTSCOPE AS A STORE. DON’T USE $SCOPE TO SHARE FUNCTIONS & VARIABLES
  • 173.
    DON’T #2: DOMMANIPULATION IN CONTROLLER
  • 174.
    DON’T #3: OVERUSEFILTERS IN YOUR HTML
  • 175.
    DON’T #4: PUTDATA YOU DON’T SHOW ON SCOPE / THIS
  • 176.
    DON’T #5: MANIPULATETHE UI DIRECTLY
  • 177.
    DON’T #6: USEGLOBAL SELECTORS IN DIRECTIVES
  • 178.
    DON’T #7: GOOVERBOARD WITH NG-REPEATS
  • 179.
    DON’T #8: OVERUSESCOPE EVENTS IN YOUR APPLICATION
  • 180.
    DON’T #9: FORGETCLEANUP IN YOUR CONTROLLERS & DIRECTIVES
  • 181.
    DON’T #10: CREATEGIANT FILES OR FOLDERS
  • 182.
    Other modules •Animation • Touch • Cookies • Resource • Security • Routing
  • 183.
  • 184.
    Directory Structure •Yeoman / Angular – seed • App – images – css – Vendors (libs) – sections – components • Tests – Spec • Mimic js folder structure – E2e • Reflect app heirarchy
  • 185.
    Modularizing your codebase • What can be reused? • What belongs in logical groups? • Group by functionality, not by type
  • 186.
    Build Process •Grunt / Ant • Glob / Minify your code base • Load at the end of body • Cache static files – Namespace by version – Use Etags • ng-boilerplate is a great starting point
  • 187.
    RequireJS • Good • Can be overkill – Lot of extra boilerplate • Great for lazy loading dependencies • Beneficial only if you have hundreds of files
  • 188.
    Dependency Injection •Use it • Depend on it • Use the [] notation (more on this later) • Capture external dependencies in Services • Use Mocks to inject dependencies in tests • Look at ng-annotate if you want to be lazy
  • 189.
    3rd party callbacks& $apply Do • Use 3rd party libraries and components • Integrate them as directives / services when possible Don’t • Forget to call $apply to let angular know when to do work
  • 190.
    Handling Data &ACLs • Resolve – Load Data – Handle auth checks – Login or not? • Interceptors – Per request level
  • 191.
    Flashing {{}} inHTML • Use ng-cloak • Use ng-bind instead of {{ }}
  • 192.
    Syntax • Usemodule. Syntax • Use safe DI • Namespace as much as possible
  • 193.
    Putting things on$scope • Minimize • What the view needs only! • The scope is heavy and expensive • Every item gets digested and dirty checked • Think twice, and thrice first
  • 194.
    The $rootScope DONOT • Use the root scope to store global state • Use the root scope as a communication mechanism • In fact, forget there is a parent $rootScope if at all possible Valid Uses: • Broadcasting and listening for events
  • 195.
    Communicating in theApp • Services • Scope  $broadcast, $emit and $on • URL Params
  • 196.
    Attribute Directives •You can create directives that are – Attributes (like ng-show, ng-hide) – Elements (<datepicker>) – Classes (<div class=“autocomplete”>) – Comments (<!– datepicker -->) • But – Always prefer to use attributes or classes – IE compatibility issues!
  • 197.
    Structuring Business Logic Controllers • should not reference DOM • should have view behavior – What should happen if user does X – Where do I get X from? Services • should not reference DOM (mostly) • are singletons • have logic independent of view – Do X operation PS: Do put DOM manipulation in Directives
  • 198.
    Using the []for DI myApp.controller(‘MyCtrl’, function($scope, $location) { }); Is the same as myApp.controller(‘MyCtrl’, [‘$scope’, ‘$location’, function($scope, $loc) { }]);
  • 199.
    Using the []for DI Until you compile your code! myApp.controller(‘MyCtrl’, function(a, xy) { }); Is not the same as myApp.controller(‘MyCtrl’, [‘$scope’, ‘$location’, function(a, xy) { }]); [] notation is the only way AngularJS knows which params are which!
  • 200.
    To $ ornot to $ • $ is used by AngularJS internals only – $scope – $http – $resource • Don’t use $ when you are naming your own services, controllers, etc.
  • 201.
    USEFUL TOOLS &LIBRARIES
  • 202.
  • 203.
  • 204.
    3rd Party Components • Wijmo • KendoUI • Angular-UI • ngModules.org
  • 205.
    Other Tools •Yeoman • Ng-Boilerplate
  • 206.
  • 207.
    Feedback • shyam@befundoo.com – Feedback? – Comments? – Suggestions? • omniscient1 on Twitter • Recommend us on LinkedIn (Fundoo Solutions) if you like it

Editor's Notes

  • #24 The model in AngularJS is the truth. Every thing in AngularJS is driven by changes to the Model, instead of standard techniques where the UI is manipulated by JS code in response to certain actions. In AngularJS, the entire aim is to change the model, and let the UI update itself to reflect the changes.
  • #27 Pure HTML No dynamic data without an associated scope / model No interactivity / business logic without an associated controller Can be handed off to a designer to style independently, without him / her needing any JS knowledge
  • #29 Never do any DOM manipulation in the controller. The controller is not the place for that
  • #30 Again, notice how we just bind to the model. Any updates to the model are automatically handled by AngularJS. The manual chore / boiler plate code of transporting data to and from the JS and the HTML is done by AngularJS. If you find yourself writing any code for that, STOP!
  • #31 The aim in AngularJS is to leverage HTML, and write your code in a Declarative manner. Your HTML should make it obvious what it is trying to do, and what it depends on.
  • #32 Again. Declarative!
  • #44 Include the angular source code, and mention an ng-app tag which tells AngularJS which parts of the page to bootstrap. Allows you to restrict angular to just a specific section of the page, if you want it to co-exist with the rest of your existing application.
  • #48 Talk about Structure Node NPM Server Client Setup
  • #53 Talk about AngularJS LifeCycle Scope & Scopes HTML loaded, then scope and controller attached Watchers Data transmit between UI and Controller Update frequency
  • #75 Also use scope communication to communicate instead of the service
  • #81 Chaining Common Error Handling Combining and waiting for multiple xhrs
  • #177 Change the model / data, let Angular do the heavy lifting
  • #181 Use ng-submit for “enter” key working