AngularJS One Day Workshop

Preview:

DESCRIPTION

Slides for the one day AngularJS workshop conducted at JsFoo 2014

Citation preview

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 AngularJSinbuilt 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. LogicAuthorization & Permissions

RenderingConcurrent

usageAnd so much

more

While hitting faster turnaround times

Feature 1

Deliver in 10 weeksFeature 2

Deliver in 2 weeksFeature 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

User Actions in the view are triggered in the controller

Model

ControllerView

Model-V-C

A Simple Model in AngularJS

Just any JSON object returned by the Server

M-View-C

Projection of the Model

Template + Scope => View

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(newVal, 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

What if we could just do this?

<tabs>

<tab title=“Home”>content here</tab>

<tab title=“Contact”>content here</tab>

</tabs>

AngularJS world

Plus the content, and the logic ofSwitching between the tabs, and somuch 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

•ReusabilityWhy

•Everywhere in AngularJS

•From Controllers to Services, from Directives to FiltersWhere

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

• Hook up Angularstep1

• Controllers & Data bindingstep2

• More controllers & using Directivesstep3

• Forms and validationstep4

• Using AngularJS servicesstep5

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 todosfrom 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 routesstep8

•Add routes for create, update, and allstep9

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 step10karma start

OR

cd step10

../node_modules/karma/bin/karma start

OR DO IT FROM WEBSTORM

Code Along – Session 3

• Left off from session 2step10

• Add a test for fetching todoliststep11

• Add a test for creating todostep12

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.jsexports.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/e2eprotractor 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 directivestep14

• Convert directive to fully contained with data passed instep15

• Delete todo and reload liststep16

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 (FundooSolutions) if you like it

Recommended