You are on page 1of 155

Modern Web Application Development Single Page Application Development using AngularJS JavaScript Overview

Static Page: The web isnt always as responsive as it could be. You would expect entering data in a web page would generate some sort of response but nothing happened. Interaction is two-way communication. But JavaScript Talks Back. JS turns a web page into an interactive. JavaScript brings a web page to life by allowing it to respond to a users input. JS can turn a web page interactive application as opposed to a static, life less page. Example:

Modern Web Page JS sits with HTML and CSS as one of three pieces of Modern Web Page Construction. HTML provides the Structure CSS adds the Style JS puts the action (injection functional sizzle, allowing the page to take action). JS springs into action when the user asks the page to perform a task. Your Web browser can handle HTML, CSS and JavaScript. Alerting the user the with a function. JS alert() function and passing it the text you want to display. JS alert() is a pop-up window, or box, that you can use to display information to the user. Functions are reusable piece of code that perform common tasks. Data Types: JS uses three basic data types: text, number, and boolean. var variablename = initial value; // variable names use CamelCase lowerCamelCase is used to name multiWord variables. the first word is all lowercase, but additional words are mixed-case. const constantname = constant value; A piece of data is undefined when it has no value. X = NaN; NaN is a value that isnt a number even though youre expecting the value to be one. parseInt() and parseFloat() converts text to a number. Use getElementById() to grab the data from your Web page. The key to accessing a web page element with JavaScript is the id attribute of the HTML tag: <input type="text" id="cakedonuts" name="cakedonuts" /> The id attribute is what you use to access the form field in JavaScript code The id attribute uniquely identifies any element in a page. The name attribute uniquely identifies a field within a form.

isNan() function Clients window width and height The client window is only the part of the browser window that displays a web page. document.body.clientWidth document.body.clientHeight Script Life Cycle 1. The browser is launched 2. User enters URL in address bar 3. The page is loaded from the web server HTML, CSS, JS and all 4. The onLoad event fires, JavaScript variables are created and initiated. 5. The user closes the browser or reloads the page 6. The script stops, JS cleans up all variables, and the page is closed. Scope of variables: Global Variables data can be seen everywhere in a script

Local Variables limited to specific block of code, such as a function Arrays stores multiple pieces of data in a single place. var showtime = new Array(); showtime*0+ = 12:30; var showTime = *12:30, 2:45, 5:00, 7:00+; Functions function name() { body } Passing information to functions: function name(arguments) { body } Returning data from functions: return value; Callback Functions: Which are called by the browser, instead of your own code. The most common use of callback functions is in handling events. <body onload=initSeats()> <img . Onclick=showSeatStatus(26)> Using Function References You can assign a function reference directly in a JS code. window.onload = initSeats; // There are no parantheses following the function name because you dont want to run the function; you just want to reference it. Anonymous Functions: It is a nameless function that handles the event. window.load = function() { initSeats(); } document.getElementById(seat26).onclick = function(evt) , showStatus(26); } An event object is passed into event handler, in this case evt argument. The event object contains information specific to each different event. Regular Expressions A regular expression is used to match patterns in text. Pattern involves physical attributes of a person. Pattern = Tall, no glasses, short hair. The pattern describes physical properties of a person that are then matched against actual people. Regular expressions allow you to do the same kind of pattern matching with strings. A text pattern involves a certain sequence of characters. Pattern = ##### This pattern involves a sequence of exactly five numeric digits. All Regular Expressions are enclosed by forward slashes. / expression / Within the expression, a collection of special symbols known as metacharacters are used in conjunction with letters and numbers. (dot) . Any character other than a new line \d Any numeric digit \w Any alphanumeric character \s A whitespace character

^ String must begin with the pattern (The string being matched cant have any text preceding the pattern) $ The String must end with the pattern. (The pattern must be the very last characters in the string). Examples: /./ (Any Single Character) A or % or 7 /\w/ (Any Alphanumeric) A or 7 /\d/ (A single digit) 7 or 2nite or catch22 /^\d/ (One digit at the beginning of a string) 7 or 007 or 2nite /\d\d$/ (Two digits at the end of a string) catch22 /\d\d\d/ (Three digits in a row) 007 /^cat/ (cat appearing at the beginning of a string) catch22 /cat$/ (cat appearing at the end of a string) incat /^\d\d\d\d\d-\d\d\d\d$/

Quantifiers precede within a regular expression, and provide control over how many times a subpattern appears in a pattern. {n} sub-pattern must appear exactly n times in a row. * sub-pattern is optional and can appear any number of times ? sub-pattern is optional, but can only appear once if does appear + sub-pattern is required, and can appear any number of times () used to group together sub-patterns much as you group together mathematical expns Examples /^\d{5}-\d{4}$/ /\w*/ /.+/ /(Hot)? ?Donuts/

A zip code pattern. Matches any number of alphanumeric characters, including an empty string Any character must appear one or more times matches a non-empty string Matches either Donuts or Hot Donuts

Validating data with regular expression var regex = /^\d{5}$/; The regular expression matches a 5-digit ZIP code. $: This object literal automatically creates a RegEx object. If(!regex.test(inputField.value)) // The zip code is invalid Date pattern: MM/DD/YYYY or MM/DD/YY /^\d{2}\/\d{2}\/\d{2,4}$/ Phone Number pattern: \^\d{3}-\d{3}-\d{4}$/ Email: /^\w+@\w+\.\w{2,3}$/ Creating space with DIV In order to display description on the page instead of alert box, we first need to define a physical area on the page as an HTML element. <div> should work fine for description text appears as its own paragraph. <div id=sometext></div> innerHTML is used to set the content on the page. document.getElementById(sometext).innerHTML = You are <strong> not </strong> alone; The DOM sees a web page as a hierarchical tree of nodes. Your page is a collection of DOM nodes. DOM nodes are classified according to their node types.

Climbing the DOM tree with properties: nodeValue The value stored in a node, only for text and attribute nodes (note elements) nodeType The type of a node, such as DOCUMENT or TEXT, but expressed as a number. childNodes Arrays containing all of the child nodes beneath a node, in the order that the nodes appear in the HTML code. firstChild The first child node beneath a node. lastChild The last child node beneath a node. Document.getElementById(sometext).nodeValue

Objects link variables (properties) and functions (methods) together inside a storage container.
The dot operator references a property or method from an object A constructor is responsible for creating an object. Every custom object requires its own constructor, which is named the same as the object. Example: Write a constructor for a Blog object that creates and initializes properties for the date and body text of a blog entry. Function Blog(body, date) { this.body = body; this.date = date; } var blogEntry = new Blog(Got the new cube, 08/04/2013); An Object class is a template, while an object instance is the thing created from the template. Defining Objects: function Card(name, address, work, home) { this.name = name; this.address = address; this.workphone = work; this.homephone=home; } Defining a Object method
function PrintCard() { line1 = "Name: "+ this.name + "<br>\n"; line2 = "Address: " + this.address + "<br>\n"; line3 = "Work Phone: " + this.workphone + "<br>\n"; line4 = "Home Phone: " + this.homephone + "<hr>\n"; document.write(line1, line2, line3, line4); }

You now have a function that prints a card, but it isn't officially a method of the Card object. The last thing you need to do is make PrintCard() part of the function definition for Card objects. Here is the modified function definition:
function Card(name,address,work,home) { this.name = name; this.address = address; this.workphone = work; this.homephone = home; this.PrintCard = PrintCard; }

The following statement creates a new Card object called tom:

tom = new Card("Tom Jones", "123 Elm Street", "555-1234", "555-9876"); tom.PrintCard();

Extending Built-In Objects:

JavaScript includes a feature that enables you to extend the definitions of built-in objects. For example, if you think the String object doesn't quite fit your needs, you can extend it, adding a new property or method. This might be very useful if you were creating a large script that used many strings. You can add both properties and methods to an existing object by using the prototype keyword. (A prototype is another name for an object's definition, or constructor function.) The prototype keyword enables you to change the definition of an object outside its constructor function. As an example, let's add a method to the String object definition. You will create a method called heading, which converts a string into an HTML heading. The following statement defines a string called title:
title = "Fred's Home Page";

This statement would output the contents of the title string as an HTML level 1 heading:
document.write(title.heading(1));

Listing 6.4 adds a heading method to the String object definition that will display the string as a heading, and then displays three headings using the method.
Listing 6.4. Adding a Method to the String Object <html> <head><title>Test of heading method</title> </head> <body> <script LANGUAGE="JavaScript" type="text/javascript"> function addhead (level) { html = "H" + level; text = this.toString(); start = "<" + html + ">"; stop = "</" + html + ">"; return start + text + stop; } String.prototype.heading = addhead; document.write ("This is a heading 1".heading(1)); document.write ("This is a heading 2".heading(2)); document.write ("This is a heading 3".heading(3)); </script> </body> </html>

First, you define the addhead() function, which will serve as the new string method. It accepts a number to specify the heading level. The start and stop variables are used to store the HTML "begin header" and "end header" tags, such as <h1> and </h1>. After the function is defined, use the prototype keyword to add it as a method of the String object. You can then use this method on any String object or, in fact, any JavaScript string. This is demonstrated by the last three statements, which display quoted text strings as level 1, 2, and 3 headers.
function Name(first,last) { this.first = first; this.last = last; }

You can add additional properties to an object you have created just by assigning them:
Fred.middle = "Clarence";

Properties you add this way apply only to that instance of the object, not to all objects of the type. A more permanent approach is to use the prototype keyword, which adds a property to an object's prototype (definition). This means that any future object of the type will include this property. You can include a default value:
Name.prototype.title = "Citizen";

Object Oriented Java Script


Prototype-based programming is a style of object-oriented programming in which classes are not present, and behavior reuse (known as inheritance in class-based languages) is accomplished through a process of decorating existing objects which serve as prototypes. This model is also known as class-less, prototype-oriented or instance-based programming. Java Script Object oriented programming Custom Object The Class: JS is a prototype-based language which contains no class statement, such as is found in C++ or Java. Instead JS uses functions as classes. Defining a class is easy as defining a function. Function Person() { } The Object (Class Instance) To create a new instance, use new operator. var p1 = new Person(); var p2 = new Person(); The constructor is called at the moment of instantiation. The Property properties are variables contained in the class. Properties defined within a class is done by keyword this, which refers to the current object. function Person(gender) { this.gender = gender; alert(Person instantiated); } var p1 = new Person(Male); alert(Person 1 is a + p1.gender); The Methods are functions and they are defined as functions. To define a method, assign a function to a named property of the classs prototype property; the name that the function is assigned to is the name that the method is called by on the object. Person.prototype.sayHello = function() { Alert(Hello method..); }

In JavaScript methods are regular function objects that are bound to a class/object as a property which means they can be invoked "out of the context". Consider the following example code: function Person(gender) { this.gender = gender; } Person.prototype.sayGender = function() { alert(this.gender); }; var person1 = new Person('Male'); var genderTeller = person1.sayGender; person1.sayGender(); // alerts 'Male' genderTeller(); // alerts undefined alert(genderTeller === person1.sayGender); // alerts true alert(genderTeller === Person.prototype.sayGender); // alerts true This example demonstrates many concepts at once. It shows that there are no "per-object methods" in JavaScript since all references to the method point to the exact same function, the one we have defined in the first place on the prototype. JavaScript "binds" the current "object context" to the special "this" variable when a function is invoked as a method(or property to be exact) of an object. This is equal to calling the function object's "call" method as follows: genderTeller.call(person1); //alerts 'Male' Inheritance Inheritance is a way to create a class as a specialized version of one or more classes (JavaScript only supports single class inheritance). The specialized class is commonly called the child, and the other class is commonly called the parent. In JavaScript you do this by assigning an instance of the parent class to the child class, and then specializing it. In modern browsers you can also use Object.create to implement inheritance. JavaScript does not detect the child class prototype.constructor see Core JavaScript 1.5 Reference:Global Objects:Object:prototype property, so we must state that manually. In the example below, we define the class Student as a child class of Person. Then we redefine the sayHello() method and add the sayGoodBye() method. // define the Person Class function Person() {} Person.prototype.walk = function(){ alert ('I am walking!'); }; Person.prototype.sayHello = function(){ alert ('hello'); }; // define the Student class

function Student() { // Call the parent constructor Person.call(this); } // inherit Person Student.prototype = new Person(); // correct the constructor pointer because it points to Person Student.prototype.constructor = Student; // replace the sayHello method Student.prototype.sayHello = function(){ alert('hi, I am a student'); } // add sayGoodBye method Student.prototype.sayGoodBye = function(){ alert('goodBye'); } var student1 = new Student(); student1.sayHello(); student1.walk(); student1.sayGoodBye(); // check inheritance alert(student1 instanceof Person); // true alert(student1 instanceof Student); // true Using Object.create the inheritance line would instead be: Student.prototype = Object.create(Person.prototype);

AngularJS
AngularJS is a client-side JavaScript framework It's used to build web applications It is prescriptive Makes creating a user interface (UI) easier through data-binding It helps organize and architect an application it has custom elements and attributes it uses dependency injection

What is AngularJS? AngularJS is a framework that helps you build front-ends for web-based applications. AngularJS is a prescriptive client-side JavaScript framework used to make single-page web apps. Note: Prescriptive Architecture vs. Descriptive Architecture A systems prescriptive architecture captures the design decisions made prior to the systems construction. It is the as-conceived or as-intended architecture. A systems descriptive architecture describes how the system has been built. It is the asimplemented or as-realized architecture. AngularJS is prescriptive in the sense that it has a recommended way of building web apps. It has its own spin on the ubiquitous Model View Controller (MVC) pattern that is especially well suited for JavaScript. In this way, Angular is prescribing a way for you to divide your application up into smaller parts. AngularJS is a framework that runs in the web browser. AngularJS is for single page apps, meaning the browser only loads the page once, but then makes asynchronous calls to the server to fetch new information. Here asynchronous means that the application can continue to function without having to stop and wait for the server to respond. Core Features of AngularJS Two-way Data Binding: Let's say you have a form to store user contact info and you want to update the addresses input box when data is returned from the server. You could do the following: <span id="yourName"></span> document.getElementById('yourName')[0].text = 'bob'; You manually seek to the element you want to change, calling a long, awkward series of DOM methods. You also have to make this call every time something causes the address to change. If we take the same example above and use data-binding we accomplish the same thing but faster. Here's our example with data-binding: <span>{{yourName}}</span> var yourName = 'bob'; Model View Whatever (MVW): MVC is a pattern for dividing an application into different parts (called Model, View, and Controller), each with distinct responsibilities.AngularJS as a "Model View Whatever" framework. In AngularJS, the View is simply your HTML with the AngularJS syntax compiled into it. Once the initial compilation cycle completes, the View can then bind to the object which is essentially the ViewModel.

HTML Templates: HTML templates are useful when you want to predefine a layout with dynamic sections to be filled in it is connected with an appropriate data structure. An example of this would be if you wanted to repeat the same DOM element over and over in a page such as a list or a table. You would define what you want a single row to look like and then attach a data structure, such as a JavaScript array, to it. The template would repeat each row for as many items in the array filling in each instance with the values of that current array item. There are plenty of templating libraries out there but most of them require you learn a new syntax. AngularJS templates are HTML and are validated by the browser just like the rest of the HTML in the page. Deep Linking: Dependency Injection: Defined a function that accepts a parameter you have leveraged dependency injection. You are injecting something that your function depends on to complete its work. Consider this code: Defining functions without DI function a () { return 5; } function b () { return a() + 1; } console.log(b()); Defining functions with DI service('a', function () { return 5; }); service('b', function (a) { return a() + 5; });

service('main', function (b) { console.log(b()); }); Overriding with DI // swap out 'b' easily by redefining it in another file: service('b', function (a) { return 1; // this is a test value }); Directives: it allows you to extend HTML to do some really powerful things. Directives provide the perfect way to merge the declarative nature of HTML and the functional nature of JavaScript into one place. Let's say you're writing an application that has a dropdown. <div class="container"> <div class="inner"> <ul> <li>Item <div class="subsection">item 2</div> </li> </ul> </div> </div> You can use a directive to make a shortcut so you only have to type: <dropdown> <item>Item 1 <subitem>Item 2</subitem> </item> </dropdown> TESTABLE: How do you REALLY know your app works? The answer is "by writing tests," but it's often more complicated than that. AngularJS makes it easy to write unit tests. Mocking out parts of your application, you can test each feature in isolation. Angular also makes it easy to write integration tests that ensure your whole stack is functioning as expected. A quick recap: AnguarJS has many benefits and features. If you are were to pick three things to remember about it, they are data-binding, testability, and "just JavaScript." Or consider the old way of writing web-apps with event handlers and DOM mutations, and think of how much easier it would make your development process to use Angular instead.

Hello Angular Example we're going to make a "Hello ___" program, where we have an input box
that fills the blank in with whatever we type into the box.

As you type into the input box, The line "Hello ___" gets filled in with the contents of the input box.

<body ng-app="helloApp"> <div ng-controller="HelloCtrl"> <p>{{greeting}} {{person}}</p> <input ng-model="person"> </div> <script> angular.module('helloApp') .controller('HelloCtrl', function ($scope) { $scope.greeting = 'Hello'; $scope.person = 'World'; }); </script> </body>

a Single Page Application is one in which we have a shell page and we can load multiple views into that. So a traditional app, as you know you typically blink and load everything again. Its not very efficient on the bandwidth, especially in the mobile world. In a SPA we can load the initial content upfront and then the different views or the little kind of miniweb pages can be loaded on the fly and embedded into the shell.

The challenges with SPA: 1. DOM Manipulation 2. History 3. Module Loading 4. Routing 5. Caching 6. Object Modeling

7. Data Binding 8. AJAX / Promises 9. View Loading Angular JS is a fully featured SPA Framework: Data Binding, MVC, Routing, Testing, jqLite, Templates, History, Factories, ViewModel, Controllers, Views, Directives, Services, Dependency Injection, Validation Getting Started with AngularJS 1. Download from angularjs.org 2. Import the angular.js file in your web page <script src=angular.min.js></script> Using Directives and Databinding Syntax: Directives start with ng i.e. ng-app, ng-model ng-model does is behind the scenes its going to add a property up in the memory called name into whats called the scope. Include the ng-app Include the ng-model Bind to that model. <html ng-app> <body> Working with Model directive and Data Binding <input type="text" ng-model="name"/> {{name}} </body> Working with Init and Repeat directive Weve now initialised our data with the ng-init. Were going to iterate through our data with the ng-repeat We simply give it the name and its going to put that name into the variable when we bind to it <div ng-init="names=['Sarath', 'Chandu', 'Teju', 'Devi']"> <ul> <li ng-repeat="myname in names">{{myname}}</li> </ul> </div> ng-init is used to initialize data to bind to and display. ng-repeat which will simply loop through all the names, and then data-bind or apply the value into the <li>. For each myname in the names variable write out the myname. Myname is just a variable. Try initializing data in body. i.e. <body ng-init=.> Repeat with Objects: Instead of having array of strings, I have an array of objects. <div ng-init="customers=[{name:'John Smith', city: 'Phoenix'}, {name:'John Doe', city: 'New York'}, {name:'Jane Doe', city: 'San Fransisco'}]"> <ul> <li ng-repeat="cust in customers">{{cust.name}} - {{cust.city}}</li> </ul> </div>

Filtering lets do a filter by and whenever they type a name instead of data-binding to it I want to use it as a filter. So were going to filter by the name property thats in our model. <div ng-init="customers=[{name:'John Smith', city: 'Phoenix'}, {name:'John Doe', city: 'New York'}, {name:'Jane Doe', city: 'San Fransisco'}]"> Enter Name: <input type="text" ng-model="name">{{name}} <ul> <li ng-repeat="cust in customers | filter:name">{{cust.name}} - {{cust.city}}</li> </ul> </div> We can also use orderBy. do another pipe and orderBy and then in quotes give it the property. <li ng-repeat="cust in customers | filter:name | orderBy:'city'">{{cust.name}} - {{cust.city}}</li> Lets say we wanted the name to be uppercase and the city to be lowercase. <li ng-repeat="cust in customers | filter:name | orderBy:'city'">{{cust.name | uppercase}} {{cust.city | lowercase}}</li>

Views, Controllers and Scope

You should be able to define a controller that you can bind to different views. Maybe you have a mobile view, you have a desktop view or whatever it may be. <div ng-controller="SimpleController"> <ul> <li ng-repeat="cust in customers">{{cust.name + ' ' + cust.city}}</li> </ul> </div> <script> function SimpleController($scope) { $scope.customers = [ {name: 'Dave Jones', city: 'Phoenix'}, {name:'Jamie Riley', city:'New York'}, {name: 'Heedy Wahlin', city: 'Atlanta'}, {name:'Thomas Winter', city: 'Seattle'} ] } </script> An ng-controller, SimpleController. Thatll automatically tie in this.

In the parameter signature. Youll see that we pass $scope. This is dependency injection thats built into AngularJS. When this controller gets used, will automatically inject a scope object in. Youll see that from there well take that object and add in a property onto it called customers which is simply an array of object literals. What this controller can do then is serve as the source of the data for the view but the controller again shouldnt know anything about the view, so how would we possibly communicate customers over? Well thats why were injecting scope. Scope is to be that view between the controller and the view. If we come up to our view up here the scope gets injected and then that scope is going to be automatically bound into the view once the view knows about this controller. When this [the controller] gets initialised the scope gets passed in but its initially empty. Well were going to add a customers property. Whats going to happen then is this controller will be used by the view. The controller itself though isnt going to be called its going to go through the scope. The scope itself is implicitly available in this case to the entire div: from the start of the div to the end of the div. Now look at the ng-repeat here. Its the same thing I did earlier in the demo, except in this case its binding to the scopes customers property

Whats going to happen now is the view, because it knows about the controller, automatically gets passed the scope. Angular does that kind of behind the scenes it just happens automatically. Were going to then control in our view what properties we want to bind to. In this case were going to bind to the customers. From here its standard data binding like weve seen earlier: we bind to the name and we bind to the city and were kind of off and running. Modify the above example with Filter

Modules, Routes and Factories

The first thing to talk about is although I created the controller in some previous demos right in the view thats not the recommended way to do it. Keep in mind you might actually have different views. You might have a mobile view, maybe one specific to iPad or Surface or something like that, and maybe have one for desktops. Its very possible. Just means Heh! Whats the name of the module youve defined in JavaScript? Creating a Module:

What exactly is the empty array for? This is where dependency injection comes in because your module might actually rely on other modules to get data.

We say Heh Angular! Create me a module called demoApp. I need to rely on another module. In this case I just called it helperModule. This would be some other JavaScript file that you might reference. telling Angular Go find that module. Go look it up wherever it is and inject it in and make it available to my controllers and directives and filters and factories and all that stuff that this particular module might have. Creating a Controller in Module <html ng-app="demoApp"> <div ng-controller="SimpleController"> <ul> <li ng-repeat="cust in customers">{{cust.name + ' ' + cust.city}}</li> </ul> </div> <script> var demoApp = angular.module('demoApp', []); var controllers = {}; controllers.SimpleController=function($scope) { $scope.customers = [ {name: 'Dave Jones', city: 'Phoenix'}, {name:'Jamie Riley', city:'New York'}, {name: 'Heedy Wahlin', city: 'Atlanta'}, {name:'Thomas Winter', city: 'Seattle'} ]; }; demoApp.controller(controllers); </script>

The Role of Routes

at some point if youre building a single page application youre going to need routes because we need to load different views into our shell page. Defining Routes

Declarative markup
ng:include Include HTML partials like cfinclude. ng:repeat Loop over collections like cfloop. ng:show / ng:hide Show or hide nodes based on a condition. ng:class Add or remove classes from nodes. ng:click / ng:change Handle user interactions with the page. Expressions Filters {{user.name}} {{user.dateRegistered | date: 'MM/yyyy'}}

Two way data binding


Form controls <input name="echo"> {{echo}} Automatic evaluation <button ng:click="value = value + 1"> {{value}}

Model-View-Controller
<form ng:controller="ProfileController" ng:submit="save()"> <h2>Hello, {{user.name}}.</h2> <p>You can edit your profile details below.</p> <label>Email <input name="user.email"></label> <label>Address <textarea name="user.address"></textarea></label> <input type="submit" value="Save"> </form> <script> function ProfileController() { this.user = {name: 'Elliott', email: 'esprehn@gmail.com'}; this.save = function() { // Ajax request to save the user }; }; </script>

Dependency Injection
Automatic injection function ProfileController($resource, activityService_) { ... }; Explicit injection function ProfileController(resource, activityService) { ... }; ProfileController.$inject = ['$resource', 'activityService'];

RESTful resources
Like ORM for REST Supports caching, bulking and JSONP Mocks provided for testing <script> // $resource is automatically injected by name. function ProfileController($resource) { var Users = $resource('/users/me'); this.user = Users.get(); this.save = function() { Users.save(this.user); }; }; </script>

Service abstraction

Define services for use in your controllers Easily swapped out for testing angular.service('profileService', function($resource) { return $resource('profiles/:id'); }); function ProfileController(profileService_) { // ... });

Create your own custom tags widgets


Define your own widgets <app:ProfileEditor profile="user"> </app:ProfileEditor> Reusable Components <jqui:Button icon="ui-icon-gear">Click Me</jqui:Button> Attributes <input name="tags" jqui:autocomplete="tagList">

Testability
No DOM manipulation in controllers Mocks provided for XHR Easily mock out services Angular services are not special JsTD and Jasmine integration

End-to-End Runner
<script> describe('ProfileController', function() { it('should save profiles', function() { browser().navigateTo('/profiles/mine'); expect(element('h2').text()).toEqual('Hello, Elliott.'); input('firstname').enter('Ethan'); element('#save').click(); browser().reload(); expect(element('h2').text()).toEqual('Hello, Ethan.'); }); }); </script>

End-to-End DSL
<script> describe('ProfileController', function() { it('should save profiles', function() { browser().navigateTo('/profiles/mine'); expect(profilePage().greeting()). toEqual('Hello, Elliott.'); profilePage().firstName().enter('Ethan');

profilePage().save(); browser().reload(); expect(profilePage().greeting()). toEqual('Hello, Ethan.'); }); }); </script>

Good example dealing with DOM. Here we will change style of an html tag by binding its style property to a model.

<!doctype html> <html > <head> <script src="angular.min.js"></script> <style type="text/css"> .style1{ border:1px #333 solid; width:300px; } .style2{ border:1px #999999; background-color:#0099FF; color:#fff; width:300px; } </style> </head> <body> <div ng-app> <input type="text" ng-model="data.source" > <h2 class="{{data.source}}">Hello AngularJS</h2> </div> </body> </html> Modules
var firstModule = angular.module("firstModule", []);

Now we will add controller to this module, notice what has been changed from the way we defined the controller above.

var firstModule = angular.module("firstModule",[]); firstModule.controller("FruitController", function ($scope){ $scope.fruits=['Apple','Banana','Watermelon','Peach']; });

Still our app does not know about our module, to use our module we need to define to our ng-app

<html ng-app="firstModule">

Simple AngularJS http://stephanebegaudeau.tumblr.com/


Expressions: In order to create the views of your application, AngularJS let you
execute expressions directly within your HTML pages.

<!DOCTYPE HTML> <html ng-app> <head> <script src="angular.min.js"></script> </head> <body> <div>1+1 = {{1+1}}</div> </body> </html>
Scope The scope is used to link the controllers and the views to which they are binded. A controller can add data and function in its scope and then they will be accessible in the view. In our case, we have used in the view a variable named users which was created in the scope by the controller UsersCtrl.

Partial Views
AngularJS is very good to build single page web applications. For those who are not familiar with this concept, it consists on a web application where you only have one real HTML page whose content can be changed in Javascript without having to download a new page. The new content is created programmatically in Javascript of with the use of templates. Those applications have advantages like performances (since you are not downloading a new HTML page each time you are navigating to a new page) and drawbacks like history management (what happens if your users click on the button back of their browser?). With AngularJS, you see that you are using a framework created by people who know what they are doing, as a result most of the problems of regular single page web applications are handled by AngularJS itself. In order to build your application, You define a main page (index.html) which acts as a container for your web application. In this page, you can bind part of your application to a specific AngularJS module with the directive ngApp. You can bind the whole page to a single AngularJS module if you want. After that, you can use the directive ngView" in order to use partial views. Your module will tell AngularJS which view should be display in the ngView element. This directive also let you separate the content of your application in dedicated files.

Code Organization in Large AngularJS and JavaScript Applications

Modularity
Hopefully the trite metaphors haven't been too tedious but here's the recap:

Your significant other is the new developer on the team who's been asked to fix a bug on one of the many screens in your app.

The developer sifts through the directory structure and sees all the controllers, models and services neatly organized. Unfortunately it tells him/her nothing about which objects are related or have dependencies on one another.

If at some point the developer wants to reuse some of the code, they need to collect files from a bunch of different folders and will invariably forget code from another folder somewhere else.

Believe it or not, you rarely have a need to reuse all of the controllers from the e-commerce app in the new reporting app you're building. You may however have a need to reuse some of the authentication logic. Wouldn't it be nice if that was all in one place? Let's reorganize the app based on functional areas:

cart/ CartModel.js CartService.js

common/

product/

directives.js filters.js

search/ o o SearchResultsController.js SearchResultsModel.js

user/

ProductDetailController.js ProductModel.js ProductService.js

LoginController.js RegistrationController.js UserModel.js UserService.js

Any random developer can now open the top-level folder and immediately gain insight into what the application does. Objects in the same folder have a relationship and some will have dependencies on others. Understanding how the login and registration process work is as easy as browsing the files in that folder. Primitive reuse via copy/paste can at least be accomplished by copying the folder into another project. With AngularJS we can take this a step further and create a module of this related code: var userModule = angular.module('userModule',[]);

userModule.factory('userService', ['$http', function($http) { return new UserService($http); }]);

userModule.factory('userModel', ['userService', function(userService) { return new UserModel(userService); }]);

userModule.controller('loginController', ['$scope', 'userModel', LoginController]);

userModule.controller('registrationController', ['$scope', 'userModel', RegistrationController]);

http://viralpatel.net/blogs/angularjs-introduction-hello-world-tutorial/
<!DOCTYPE html> <html ng-app> <head> <title>Hello World, AngularJS - ViralPatel.net</title> <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js "></script> </head> <body> Write some text in textbox: <input type="text" ng-model="sometext" /> <h1>Hello {{ sometext }}</h1> </body> </html>

ng-app
First thing that we notice is an attribute ng-app within <html> tag. This attribute tells the Angular to be active in this portion of the page. So in our case entire document. If you want to enable Angular only at specific location in your webpage then you can define ng-app attribute to any DIV or other tag.

ng-model and Two way data binding


We define attribute ng-model in textbox as ng-model=sometext. ng-model binds the state of textbox with model value. In our case we define a model sometext. This model value is bound with the value of textbox using ng-model attribute. Thus when the textbox value changes, Angular automatically changes the model sometext with this value. This is called Two way data binding. Similarly, if we change the model value than Angular will change the value of textbox. Two way data binding is the core of Angulars magical spell. It just works. Youll get to know about it more once we start adding complexity in our application. AngularJS two-way data binding is its most notable feature and reduces the amount of code written by relieving the server backend from templating responsibilities.

{{ sometext }}
Note how we wrap our model value in double curly braces. This tell Angular to bind the value of modelsometext in place of {{ sometext }}. Thus any change in sometext model value changes the text inside <h1> tag.

ng-show / ng-hide
Now lets further modify our demo and add one more Angular attribute ng-show. In below code, we added attribute ng-show=sometext to <h1> tag.
<!DOCTYPE html> <html ng-app> <head> <title>Hello World, AngularJS - ViralPatel.net</title> <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js "></script> </head> <body> Write some text in textbox: <input type="text" ng-model="sometext" /> <h1 ng-show="sometext">Hello {{ sometext }}</h1> </body> </html>

Filter uppercase and lowercase


As its name suggest, this filter convert the expression into uppercase letters. Lets check a quick demo. Lets modify few lines from our above example and use uppercase filter.
<!DOCTYPE html> <html ng-app> <head> <title>Hello World, AngularJS - ViralPatel.net</title> <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>

</head> <body>

Write some text in textbox: <input type="text" ng-model="sometext" />

<h1>Hello {{ sometext }}</h1>

<h4>Uppercase: {{ sometext | uppercase }}</h4> <h4>Lowercase: {{ sometext | lowercase }}</h4>

</body> </html>

1. What are Scopes?


Before we get into Controllers let us understand Scopes. Scope is nothing but an object that Glues the View with Controller. They hold the Model data that we need to pass to view. Scope uses Angulars two-way data binding to bind model data to view. Imaging $scope as an object that links Controller to the View. It is controllers responsibility to initialize the data that the view needs to display. This is done by making changes to $scope. Let us see a small Hello World application to understand $scope.
<!DOCTYPE html> <html ng-app> <head> <title>Hello World, AngularJS - ViralPatel.net</title> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script> </head> <body> <div ng-controller="ContactController"> Email:<input type="text" ng-model="newcontact"/> <button ng-click="add()">Add</button> <h2>Contacts</h2>

<ul> <li ng-repeat="contact in contacts"> {{ contact }} </li> </ul>

</div> <script type="text/javascript"> function ContactController($scope) { $scope.contacts = ["hi@email.com", "hello@email.com"];

$scope.add = function() { $scope.contacts.push($scope.newcontact); $scope.newcontact = ""; } } </script> </body> </html>

1.2. ng-controller
This attribute defines a Controller to be bound with the view. In this case we defined a controller called ContactController in DIV using ng-controller attribute. Thus whatever we put inside that DIV, the ContactController will have its influence on it. ContactController is nothing but a plain vanilla JavaScript function. In the demo we defined it as function. Also see the definition of ContactController function. There is an object $scope which we pass as an argument. This object is used to bind the controller with view. When AngularJS initialize this controller, it automatically creates and injects the $scope object to this function using dependency injection (More on dependency injection in coming tutorials). For now just note that the $scope object is created by Angular and injected in this controller function.

2. Initial state of a scope object


Typically, when you create an application you need to set up an initial state for an Angular scope. In our case we need initial state to be list of contacts. On $scope object, we defined an array called contacts:
$scope.contacts = ["hi@email.com", "hello@email.com"]

When Angular initilize this function (ContactController), it automatically creates this array and binds it in$scope object. Then in our view we display the array using ng-repeat attribyte. Thus, $scope provides us with a way to pass/retrieve objects from Controller to View and viceversa.

2.1. ng-click
It is also possible to define functions on $scope and use the same in View. In our demo, we created a function add() on $scope and use it on Add button click:
$scope.add = function() { ... }

The function add() is bound to Add button using an attribute ng-click. ng-click binds the click event on the button or link or any clickable element with the function that is defined within $scope. So in this case, whenever Add button is clicked, the add() method on $scope will be called. In add() method we add (or push) a string in contacts array. This is the string that user types in textbox. Note that we bind textbox using ng-model attribute.
<input type="text" ng-model="contact" ...

This textboxs value we got in $scope.contact as we bind it using ng-model attribute. Pretty nice, isnt it!!

3. How to define a Controller


So we got some basic idea of what Controllers are. Just plain vanilla JavaScript functions that we add in an Angular application to add some business logic and bind the view with model. In the above demo, we defined controller as JavaScript function. While this is the easiest way to define them, but is certainly not advisable one. If your application grows, soon youll have bunch of controllers lying here and there in code poluting the JavaScript namespace. So instead of defining controller as:
function ContactController($scope) {

//...

3.1. AngularJS Modules


So what-the-heck are modules? Well, modules are the logical entities that you divide you app in. So your app can contain several modules (like Transaction, Report, etc.). Each module represent a logical entity within the app.

Furthermore, each modules have several Controllers. As referred in above diagram, a module can contain one or more controllers and views. We havent touch based on Views. We will see how each module can be linked with view using Routing in AngularJS in our next tutorial. For now just assume that each controller has one or more views linked to it. So in this case, we can add one or more controllers to a module. Let us check the syntax to create a module and add controller to it:
var myApp = angular.module('myApp',[]);

myApp.controller('ContactController', ['$scope', function($scope) { $scope.contacts = ["hi@email.com", "hello@email.com"];

$scope.add = function() { $scope.contacts.push($scope.contact);

$scope.contact = ""; } }]);

In above example we created a module called myApp using angular.module() method. Then we added a controller ContactController to this module. This is just an alternate way of defining a controller but recommended one. Notice how controller is declared using myApp.controller() method. We passed an array to this method. First argument of array is string $scope and next is the function itself that representContactController. We explicitly told Angular that we have one argument (dependency) to our ContactController which is $scope. This is useful when you Minify or obfuscate JavaScript for production release. In that case the argument $scope might be renamed to $s, but because we defined string $scope as first argument, Angular is aware that first dependency to this controller is $scope object. To cut it short, always stick to the above way of defining controllers.

4. Nested Controllers
We can declare the scope of controller in our HTML page using ng-controller attribute. For example:
<div ng-controller="CarController"> ... </div>

We can declare number of controllers and nest them within each other. For example:
<div ng-controller="CarController"> My name is {{ name }} and I am a {{ type }}

<div ng-controller="BMWController"> My name is {{ name }} and I am a {{ type }}

<div ng-controller="BMWMotorcycleController"> My name is {{ name }} and I am a {{ type }}

</div>

</div> </div>

<script> function CarController($scope) {

$scope.name = 'Car'; $scope.type = 'Car';

function BMWController($scope) {

$scope.name = 'BMW';

function BMWMotorcycleController($scope) {

$scope.name = 'BMWMotorade'; $scope.type = 'Motorcycle';

</script>

4.1. Online Demo


Play on JSFiddle http://jsfiddle.net/viralpatel/gWz4K/

In above demo, notice how each nested Controllers scope override the scope of parents controller. First we defined a controller CarController which defines two variables name and type within scope. NextBMWController is nested within CarController using ng-controller attribute. BMWController overridesname attribute and change it to BMW. It does not change type attribute so type attribute is still Car.
BMWMotorcycleController is the inner-most controller defined within controllers hierarchy. It

overrides both name and type attribute of scope. This way you can nest one controller within another and take advantage of parent controllers attributes whenever needed.

5. Inheritance in Controllers
In order to take advantage of inheritance of scope in Nested controllers, one has to define Controllers one into another using ng-controller attribute. Sometimes you dont want to define controllers like this but still want to use power of inheritance within controllers. May be you want to put common logic into BaseController and use it in all the child controllers. In order to achieve this, we must use $injector object that AngularJS provides.
<div ng-controller="BMWController">

My name is {{ name }} and I am a {{ type }}

<button ng-click="clickme()">Click Me</button>

</div>

<script> function CarController($scope) {

$scope.name = 'Car'; $scope.type = 'Car';

$scope.clickme = function() {

alert('This is parent controller "CarController" calling'); }

function BMWController($scope, $injector) {

$injector.invoke(CarController, this, {$scope: $scope});

$scope.name = 'BMW';

} </script>

5.1. Online Demo


Play on JSFiddle http://jsfiddle.net/viralpatel/WCZcZ/ We define two controllers, CarController an BMWController. CarController defines two attributes name and type on $scope and also defines one method clickme(). BMWController just override name attribute. Notice that it does not have name and clickme defined within its body. These attributes are defined by parent controller in this case CarController. Within BMWController, we initialize CarController and bind it into current scope using $injector.invoke() method. Once this is done, notice how in HTML page the BMWController points to its parents attributes.

6. End to end application using AngularJS Controller


Let us apply the knowledge that we acquired so far and create a ContactManager application. Following are some basic requirements of this application: 1. User can add new contact (name, email address and phone number) 2. List of contacts should be shown 3. User can delete any contact from contact list

4. User can edit any contact from contact list Following is the HTML code which defines a FORM to save new contact and edit contact. And also it defines a table where contacts can be viewed.

6.1. The HTML


<div ng-controller="ContactController"> <form> <label>Name</label> <input type="text" name="name" ng-model="newcontact.name"/> <label>Email</label> <input type="text" name="email" ng-model="newcontact.email"/> <label>Phone</label> <input type="text" name="phone" ng-model="newcontact.phone"/> <br/> <input type="hidden" ng-model="newcontact.id" /> <input type="button" value="Save" ng-click="saveContact()" /> </form> <table> <thead> <tr> <th>Name</th> <th>Email</th> <th>Phone</th> <th>Action</th> </tr> </thead> <tbody> <tr ng-repeat="contact in contacts"> <td>{{ contact.name }}</td> <td>{{ contact.email }}</td> <td>{{ contact.phone }}</td>

<td> <a href="#" ng-click="edit(contact.id)">edit</a> | <a href="#" ng-click="delete(contact.id)">delete</a> </td> </tr> </tbody> </table> </div>

Just note that we have used ng-model, ng-click and ng-repeat attributes from Angular so far. To add life to this application, we add following JavaScript code.

6.2. The JavaScript


var uid = 1;

function ContactController($scope) {

$scope.contacts = [ { id:0, 'name': 'Viral', 'email':'hello@gmail.com', 'phone': '123-2343-44' } ];

$scope.saveContact = function() {

if($scope.newcontact.id == null) { //if this is new contact, add it in contacts array $scope.newcontact.id = uid++; $scope.contacts.push($scope.newcontact);

} else { //for existing contact, find this contact using id //and update it. for(i in $scope.contacts) { if($scope.contacts[i].id == $scope.newcontact.id) { $scope.contacts[i] = $scope.newcontact; } } }

//clear the add contact form $scope.newcontact = {}; }

$scope.delete = function(id) {

//search contact with given id and delete it for(i in $scope.contacts) { if($scope.contacts[i].id == id) { $scope.contacts.splice(i,1); $scope.newcontact = {}; } }

$scope.edit = function(id) {

//search contact with given id and update it for(i in $scope.contacts) { if($scope.contacts[i].id == id) { //we use angular.copy() method to create //copy of originial object $scope.newcontact = angular.copy($scope.contacts[i]); } } } }

First thing to note, we created a variable uid and set its initial value to 1. This variable is used to generate unique ids for each new contact we save. In real life application you may want to do this at backend. We defined one controller ContactController. This controller defines following objects within $scope:
Scope object Type Comment

$scope.contacts

Array

Array to store contact objects. In real life app, this should be maintained at server side. Saves the newcontact object within contacts array. Check if contact is new or is being updated Delete the contact object from contacts list based on id specified

JavaScript $scope.saveContact Function JavaScript Function JavaScript Function

$scope.delete

$scope.edit

Update the contact object in contacts list based on id specified

6.3. Online Demo

Play on JSFiddle http://jsfiddle.net/viralpatel/JFYLH/ You can add new contact using the above form. Once new contact is saved, the list showing contacts will be updated. Each contact can be edited and deleted. You got the gist

Building a simple single page application using AngularJS


I am going to walk you through building a SPA (single page application) usingAngularJS, Google's latest JavaScript MVC framework. After developing applications using Backbone.js, Spine.js and good ol' jQuery I fell in love with AngularJS. It makes development of SPAs actually fun removing a lot of the boilerplate that most of the other frameworks make you write to get a simple app started. The app we are going to build today is a simple multipage website that will read data in from a static JSON file. We will be covering setting up AngularJS, routing, rendering partials, communication between controllers and loading JSON asynchronously.

Download the source code View the demo

Sections

Setting up AngularJS Routing Rendering partials Loading JSON Communicating between controllers

Before we get started it's a good idea to watch the intro videos on angularjs.org as they cover most of the basics. I'm going to assume that you understand the concepts of how the controller binds $scope with the views and how the ng-modeldirective works.
Setting up AngularJS

This tutorial will require you to run these files via a web server. If you have apache/MAMP/WAMP set up you should be able to create a new directory under your webroot and access via localhost. I like to run the npm module nws which creates a web server in the current directory allowing me to get started quickly.
Html

The first thing you will want to do is setup your module. You do this by adding the ngapp attribute to your html tag. In the case of our application we will call our module Site.

<html lang="en-US" ng-app="Site">

The next thing we want to do is set up a controller. The controller is bound to the element you add it to and it's children. We are going to add an AppController to our body tag which allows the entire body to inherit from this controller. To add a controller you use the ng-controller attribute.

<body ng-controller="AppController">

Here is a template including AngularJS from CDNJS that I will be using throughout this tutorial.
JavaScript

Now that our html is set up we need to create the module and controller in our/js/site.js file that is included.

var Site = angular.module('Site', []);

function AppController ($scope) { }

The first line creates our Site module and the function defines our AppController. The controller receives one argument (at the moment) $scope which binds models between the view (html) and controller.
Routing

If you took a look at the template above you will have noticed that there are three links in the nav bar: Home, About and Contact. We want to be able to route to these links and load a section from the JSON file based on the slug. The first thing we need to do is configure our Site module to use the $routeProviderand then set up our routes.

Site.config(function ($routeProvider) { $routeProvider .when('/page/:slug', {templateUrl: 'partials/page.html', controller: 'RouteController'}) .otherwise({redirectTo: '/page/home'}); });

We are passing in an anonymous function to the modules config method. In the function we are passing in Angular's $routeProvider service which allows us to define routes. The two methods we are using are when() which takes a path and hash of options including the templatePath and controller and otherwise() which allows us to redirect to a route if one is not found. We are defining one route for this application /page/:slug. This path contains the:slug parameter, we can use this later using the $routeParams service to extract the page data from the JSON. We are also setting a controller for this route (RouteController). This controller is in charge of binding the page content to the view.

function RouteController ($scope, $routeParams) { // Getting the slug from $routeParams var slug = $routeParams.slug;

// We need to get the page data from the JSON // $scope.page = ?; }

Now when you try and visit the page you should be redirected to and type in anything else it will redirect you back.
Rendering Partials

/#/home

and if you try

When we defined our route we set a templateUrl. This points to a static html file that contains 2 simple expressions containing properties that will be bound to the RouteController's $scope.

<!-- partials/page.html --> <h1>{{page.title}}</h1> {{page.content}}

To include this partial into your layout you need to use the <ng-view></ng-view>directive. This will automatically be replaced with the partial set in the routes. You can see that this is included already in the template provided above.
Loading JSON

Let's load some data into this application. I've created a simple static JSON data store (in real life this would probably be generated by an API) which we will load in via Ajax when the application starts.

// pages.json { "home": { "title": "Home", "content": "This is the home page. Welcome" }, "about": { "title": "About", "content": "This is the about page. Welcome" }, "contact": { "title": "Contact",

"content": "This is the contact page. Welcome" } }

We should only load the JSON file once, cache it to a variable and access the variable when we need the data. Let's use Angular's $http service to grab the JSON file. To use the $http service we will need to pass it as an argument to theAppController.

function AppController ($scope, $rootScope, $http) { // Load pages on startup $http.get('/pages.json').success(function (data) { $rootScope.pages = data; }); }

We are also passing in $rootScope which all scopes inherit from. We do this so this so that we can access the pages JSON data in our RouteController. We can then access the page data by using the slug we captured earlier and bind it to the scope so it's accessible in our partial.

function RouteController ($scope, $rootScope, $routeParams) { // Getting the slug from $routeParams var slug = $routeParams.slug;

$scope.page = $rootScope.pages[slug]; }

Communicating between controllers

We've already demonstrated one way to communicate between controllers using the $rootScope. Another option is using events. In Angular you can emit events and listen to events in different controllers while passing data from the emitter to the listener. We want to pass the slug from the RouteController to the AppController so that we can set the active class on the current menu link. Angular has a ng-class directive which allows you to add conditional classes to elements.

<li ng-class="{active: slug == 'home'}"><a href="/#/page/home">Home</a></li> <li ng-class="{active: slug == 'about'}"><a href="/#/page/about">About</a></li>

<li ng-class="{active: slug == 'contact'}"><a href="/#/page/contact">Contact</a></li>

You can see that the RouteController is emitting the slug and the AppController is listening for the slug which then sets it onto it's scope and exposes it to the view.

function AppController ($scope, $rootScope, $http) { // Load pages on startup $http.get('/pages.json').success(function (data) { $rootScope.pages = data; });

// Set the slug for menu active class $scope.$on('routeLoaded', function (event, args) { $scope.slug = args.slug; }); }

function RouteController ($scope, $rootScope, $routeParams) { // Getting the slug from $routeParams var slug = $routeParams.slug;

$scope.$emit('routeLoaded', {slug: slug}); $scope.page = $rootScope.pages[slug]; }

I hope you guys enjoyed this walkthrough. I will be writing more about AngularJS in the future. If you guys have any questions about this post or have any topics you are interested in let me know in the comments.

Angular JS Concepts Overview


1. <!doctype html> 2. <html ng-app> 3. <head> 4. <script src="http://code.angularjs.org/1.0.6/angular.min.js"></script> 5. </head> 6. <body> 7. <p ng-init=" name='World' ">Hello {{name}}!</p> 8. </body> 9. </html>

1. 2. 3. 4. 5. 6. 7. 8. 9.

The browser loads the HTML and parses it into a DOM The browser loads angular.js script Angular waits for DOMContentLoaded event Angular looks for ng-app directive, which designates the application boundary The Module specified in ng-app (if any) is used to configure the $injector The $injector is used to create the $compileservice as well as $rootScope The $compile service is used to compile the DOM and link it with $rootScope The ng-init directive assigns World to thename property on the scope The {{name}} interpolates the expression toHello World!

Scope
The scope is responsible for detecting changes to the model section and provides the execution context for expressions. The scopes are nested in a hierarchical structure which closely follow the DOM structure. (See individual directive documentation to see which directives cause a creation of new scopes.) The following example demonstrates how the name expression will evaluate into a different value depending on which scope it is evaluated in. The example is followed by a diagram depicting the scope boundaries.
1. <!doctype html> 2. <html ng-app> 3. <head> 4. <script src="http://code.angularjs.org/1.0.6/angular.min.js"></script> 5. <script src="script.js"></script> 6. </head> 7. <body> 8. <div ng-controller="GreetCtrl"> 9. Hello {{name}}! 10. </div>

11. <div ng-controller="ListCtrl"> 12. <ol> 13. <li ng-repeat="name in names">{{name}}</li> 14. </ol> 15. </div> 16. </body> 17. </html>

How to get started (Part 1 of the AngularJS - from beginner to expert in 7 steps series)
This is the first post of AngularJS - from beginner to expert in 7 steps series. AngularJS redefines how to build front-end applications. Instead of being afraid to cross the boundary between HTML and JavaScript, it takes it head-on. Application frameworks, like Backbone, EmberJS, and others, require developers to extend from JavaScript objects that are specific to their frameworks. Although this approach has its merits, it unnecessarily pollutes your object space and requires you to have intimate knowledge of abstract objects that exist in memory. But we accept it because the web wasnt originally designed to be as interactive as we expect it to be today, and we need frameworks to help us close the gap between JavaScript and HTML. AngularJS closes that gap. Instead of manipulating the DOM directly, you annotate your DOM with metadata (directives), and Angular manipulates the DOM for you. AngularJS also does not depend on (or exclude the use of) any other framework. You can even build AngularJS apps in non-AngularJS frameworks. It just works. Sound awesome? It is. In this 7-part series were going to walk you through how to get started writing serious apps with AngularJS - even if youve never touched it before. Follow along on this journey, and well teach you how to become an expert AngularJS developer.

First things first: When should you use AngularJS?


AngularJS is an MV* framework that is ideal for use when building client-side singlepage apps. It is not a library, but aframework for building dynamic web pages. It focuses on extending HTML and providing dynamic data binding, and it plays well with other frameworks (e.g., jQuery).

If you are building a single-page app, AngularJS will be perfect for you. Gmail, Google Docs, Twitter, and Facebook all fit into the AngularJS sweet spot. Game development and other apps that heavily manipulate the DOM or need pure speed are not good fits for AngularJS. Now that weve gotten through that intro, here is the first topic you need to understand in order to learn AngularJS:

1. How to start writing an app


Throughout this tutorial series, we are going to be building an NPR audio player that will show us the current stories on the show Morning Edition and play them in our browser. To see the fully finished demo, head over here. When writing an AngularJS app, we write the behavior and interaction together alongside the presentation. Writing this way can be confusing at first, especially if you have experience with other frameworks where the two are generally separate. Once you get the hang of it, itll become second nature. Lets look at the simplest app you can build with AngularJS:
<!doctype html> <html ng-app> <head> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min. js"></script> </head> <body> <div> <input type="text" ng-model="yourName" placeholder="Enter a name here"> <h1>Hello, {{ yourName }}!</h1> </div> </body> </html>

Try it

Hello, !
As you can see, you get bi-directional data binding without any work. Bi-directional data binding means that if you change data on the back end, your changes will show up in your view automagically (actually, theres no magic involved; well get into how this works soon). Similarly, if you change data in your view (e.g., by typing into a text box), it will automatically update your model. So what did we do in our app?

ng-app ng-model=yourName {{ yourName }}

First, we used our most important (and most easily forgotten) term: the ng-app attribute on the <html> tag. Without this tag, the AngularJS process does not start. Second, we told AngularJS that we want to set up bi-directional data binding on the yourName model on the page. Third, we told AngularJS to display the data yourName in the directive template called {{ yourName }}. Thats it. Weve created a dynamic app that would ordinarily have taken much longer and many more lines of code to build: We did not have to specify any rules on bi-directional data binding, we didnt have to write any updating code, we didnt have to specify any models, and, in fact, we havent even touched JavaScript yet. We wont have to do that until we want to build apps with more customized behavior. As youll see, all of the above just works because of the power of AngularJSs design.

Building your app


In this section well discuss an app well call myApp. You can follow along with our series by git cloning the repository (instructions below) or by following along with our instructions. Create an index.html file with the following content:
<!doctype html> <html ng-app="myApp">

<head> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min. js"></script> <script src="js/main.js"></script> </head> <body> </body> </html>

Then, make a directory called js and make a file in that directory called main.js, like so:
mkdir js touch js/main.js

This HTML page will load both AngularJS and our app that well write in main.js. Almost all of the work that we will do in this section will be in the main.js file. In order to extend and customize our app, well need to write some JavaScript. All the JavaScript that we will write will go into our main.js file.

angular.module
To define an AngularJS app, we first need to define an angular.module. An Angular module is simply a collection of functions that are run when the application is booted. (Were not going to discuss configuration and run blocks in this series, but well address them in future sections.) Next, we need to define the module in our main.js file:
var app = angular.module('myApp', []);

This line creates the Angular module named myApp. (Dont worry about the second argument the empty array, [] for now. Well get to it.) Now, we want to instantiate our myApp module on our page and tell Angular where in the DOM tree our app lives. To instantiate the module in a page, well be using the ngapp directive, which tells Angular that we want our module to own that part of the DOM tree. We can instantiate our own app (module) by simply passing the name of our app as the value in our index.html file:

<html ng-app="myApp">

When we refresh the page, Angular will bootstrap myApp. We can set ng-app on any element in the DOM, and thats where Angular will launch on the page. This step is how we can write an Angular app inside of any web page, even if the rest of the application isnt written in Angular.
<h2>I am not inside an AngularJS app</h2> <div ng-app="embeddedApp"> <h3>Inside an AngularJS app</h3> </div>

For an app that will take over the entire page, you can place the ng-app directive on the html element. Once weve defined our app, we can start building out the rest of the application. Well build using $scope, which is one of the most important Angular concepts. We will cover the $scope service in depth in Part 2 of our 7-part series. So there we have it - the basic structure for an Angular app. Well use this as a starting point to build our NPR player. Update: Read the next section of the series here. The official repository for the beginner series is available as a git repo here: https://github.com/auser/ng-newsletter-beginner-series. To get this repo locally, ensure you have git installed, clone the repo, and check out the part1 branch:
git clone https://github.com/auser/ng-newsletter-beginnerseries.git git checkout -b part1

Want to know when Part 2 and every article in this series is released? Sign up for ngnewsletter below. This is the second post of AngularJS - from beginner to expert in 7 steps. We started our first post by showing you how to start out building an AngularJS app. In this post, well discuss a fundamental concept in understanding how AngularJS works and how you can use it to your advantage.

Throughout this tutorial series, we are going to be building an NPR audio player that will show us the current stories on the show Morning Edition and play them in our browser. To see the fully finished demo, head over here.

Part 2. Scopes
A $scope is an object that ties a view (a DOM element) to the controller. In the Model-ViewController structure, this $scopeobject becomes the model. It provides an execution context that is bound to the DOM element (and its children). Although it sounds complex, the $scope is just a JavaScript object. Both the controller and the view have access to the $scopeso it can be used for communication between the two. This $scope object will house both the data and the functions that well want to run in the view, as well see. All AngularJS apps have a $rootScope. The $rootScope is the top-most scope that is created on the DOM element that contains the ng-app directive. This is where AngularJS binds data and functions when explicit $scopes are not set in the page. This is why the example inpart 1 works. In this example, were working with the $rootScope. We add an attribute on the scope of name in our main.js file. By putting this function in the app.run function, well guarantee that it will run prior to the rest of the app. You can think of the runfunction being the main method of the angular app.
app.run(function($rootScope) { $rootScope.name = "Ari Lerner"; });

Now, anywhere in our view, we can reference this attribute using the expression/template: {{ }}, like so:
{{ name }}

Well go more in-depth into how the expression template syntax works later in this series.

See it:
Ari Lerner In summary:

Anything that we attach to this $scope object will become available to the view. Likewise, any changes that the controller makes to the model will show up as changes in the view.

To really see the power of scopes, lets attach a controller to a DOM element, which will create a $scope for the element and allow us to interact with it.

ng-controller
To explicitly create a $scope object, well attach a controller object to a DOM element using the ng-controller directive on an object, like so:
<div ng-controller="MyController"> {{ person.name }} </div>

The ng-controller directive creates a new $scope object for the DOM element and nests it in the containing $scope. In this example, the parent $scope of the div with ngcontroller is the $rootScope object. The scope chain looks like this:

Now, MyController sets up a $scope that we can access from inside the DOM element. In this case, were going to create a person object on the $scope of MyController, in main.js:
app.controller('MyController', function($scope) { $scope.person = { name: "Ari Lerner" }; });

Now we can access this person object in any child element of the div where ngcontroller='MyController' is written because it is on the $scope.

See it
Ari Lerner

With one exception, all scopes are created with prototypal inheritance, meaning that they have access to their parent scopes. By default, for any property that AngularJS cannot find on

a local scope, AngularJS will crawl up to the containing (parent) scope and look for the property or method there. If AngularJS cant find the property there, it will walk to that scopes parent and so on and so forth until it reaches the $rootScope. The one exception: Some directives can optionally create an isolate scope and do not inherit from their parents. For instance, say we have a ParentController that contains the user object and a ChildController that wants to reference that object:
app.controller('ParentController', function($scope) { $scope.person = {greeted: false}; });

app.controller('ChildController', function($scope) { $scope.sayHello = function() { $scope.person.greeted = true; } });

When we bind the ChildController under the ParentController in our view, we can reference the property on the parent scope just as if it were on the ChildController:
<div ng-controller="ParentController"> <div ng-controller="ChildController"> <input type="text" ng-model="person.name" placeholder="Name"></input> <a ng-click="sayHello()">Say hello</a> </div> {{ person }} </div>

See it
Say hello Reset {"greeted":false}

Integrating in myApp
Now lets use the power of the $scope to manage our NPR app. We left off last article having just defined the app module. Now, lets start breaking up our DOM structure and build our fundamental functionality. Just like we saw in the example above, well create a root controller called PlayerController. Our PlayerController will be responsible for keeping track of our audio element and will handle fetching our listing of NPR programs. Lets create both of our controllers, back in main.js:
var app = angular.module('myApp', []);

app.controller('PlayerController', ['$scope', function($scope) { }]);

app.controller('RelatedController', ['$scope', function($scope) { }]);

Audio
These controllers dont do much yet, so lets get some audio going on in the app. In this tutorial, well be using the HTML5audio element, so make sure you have an HTML5compliant browser (we prefer Google Chrome). To add an audio element, we can either add it in the HTML or in our controller. Since well be interacting with the audio element primarily in our controller, it makes most sense to create it here. In our PlayerController, lets create an audio element. Well store it on our scope, which, as you know by now, means that well connect the view to the controller through the $scope object.
app.controller('PlayerController', ['$scope', function($scope) { $scope.audio = document.createElement('audio'); }]);

Now, this setup is kind of boring, as it doesnt do very much yet. Well cover fetching the data in the next part of our series, so for now well hardcode a .mp4 url. In the same PlayerController, set the src of the audio file to an .mp4 URL to which you have access. For the purpose of convenience, were using an NPR audio file that we are hosting, but we can point to any URL. Simply set your audio source as the URL of the audio file.
app.controller('PlayerController', ['$scope', function($scope) { $scope.playing = false; $scope.audio = document.createElement('audio'); $scope.audio.src = '/media/npr.mp4'; }]);

Try it
Play Playing audio: false

The audio wont play unless we tell it to play. To do that, we can simply call $scope.audio.play(), and the HTML5 audio element will take over and start playing from the mp4 stream. We can provide an interactive element to the user by creating a button that binds to an action on the $scope. Well discuss this more in-depth in the next section, however the HTML for the view above looks like:

<div ng-controller="PlayerController"> <button ng-click="play()" class="button" ngshow="!playing">Play</button> <button ng-click="stop()" class="button alert" ngshow="playing">Stop</button> Playing audio: <b>{{ playing }}</b> </div>

Notice that we dont have to reference the audio element we create on the scope. This is because we are creating it in the controller when the controller is loaded using document.createElement("audio") . Note that we are going to refactor this component later in the tutorial series. Its generally a bad idea to manipulate DOM components inside of a controller (thanks Brad Green for pointing this out as a note). Were keeping this component here to maintain simplicity. Weve added a few variables in the view that we are keeping track of in on the $scope. Were using a few advanced concepts that well discuss in detail throughout the series, so do not worry if it doesnt all make sense immediately:
app.controller('PlayerController', ['$scope', function($scope) { $scope.playing = false; $scope.audio = document.createElement('audio'); $scope.audio.src = '/media/npr.mp4'; $scope.play = function() { $scope.audio.play(); $scope.playing = true; }; $scope.stop = function() { $scope.audio.pause(); $scope.playing = false; }; $scope.audio.addEventListener('ended', function() { $scope.$apply($scope.stop()); });

}]);

Thats a solid introduction into AngularJSs $scope service. In the next section, well cover bi-directional data binding in AngularJS. Update: Check out part3 of our series. The official repository for the beginner series is available as a git repo here: https://github.com/auser/ng-newsletter-beginner-series. To get this repo locally, ensure that you have git installed, clone the repo, and check out the part2 branch:
git clone https://github.com/auser/ng-newsletter-beginnerseries.git git checkout -b part2

Want to know when Part 3 and every article in this series is released? Sign up for ngnewsletter below. This is the third post of AngularJS - from beginner to expert in 7 steps. We started our first post by showing you how to start out building an AngularJS app. In the second post, we discussed how scopes and the $scope service work. Throughout this tutorial series, we are building an NPR audio player that will show us the current stories on the showMorning Edition and play them in our browser. To see the fully finished demo, head over here.

3. Data binding
We can make our app a bit more interesting by binding an input field to the person.name attribute. This step sets up a bi-directional binding from the input field to the page.

Bi-directional in this context means that if the view changes the value, the model sees the change, and if the model changes the value, then the view will see the change. AngularJS sets this up automatically for you. Well discuss thedigest_loop in depth in an upcoming article, if youre curious how it works. To set up this binding, well use the ng-model function on the input, like so:
<div ng-controller="MyController"> <input type="text" ng-model="person.name" placeholder="Enter your name" /> <h5>Hello {{ person.name }}</h5> </div>

Now that we have a binding set up (yes, its that easy), we can see how the view changes the model:

Try it
Hello
As you type in the input box, youll see that the name underneath changes automatically. That change illustrates how our data binding works in one direction, from the view to the model. We can also change the model on the (client-side) back end and see it reflected on the front end.

To illustrate our data binding from back end to front end, lets make a clock function in our MyController model that will update a value on the $scope. In this example, well create a clock that will tick every second (as clocks usually do) and change the data on the clock variable:
app.controller('MyController', function($scope) { $scope.person = { name: "Ari Lerner" }; var updateClock = function() { $scope.clock = new Date(); }; var timer = setInterval(function() { $scope.$apply(updateClock); }, 1000); updateClock(); });

As you can see, as we change the clock variable on the model, the view automatically updates to reflect our changes. We can show the clock variable thats attached on the $scope in the view simply by surrounding it in {{ }}:
<div ng-controller="MyController"> <h5>{{ clock }}</h5> </div>

See it it
"2013-08-10T11:23:13.597Z"

Interaction
Notice that we have bound data to the input field above. We dont have to limit this data binding to only data. We can also call functions on the $scope (as mentioned previously). To bind buttons or links (or any DOM element, really), well use another built-in directive, ng-click. The ng-click directive binds the click event to the method (the mousedown browser event) to the DOM element (i.e., when the browser fires a click event on the DOM element, the method is called). Similar to our previous example, the binding looks like:

<div ng-controller="DemoController"> <h4>The simplest adding machine ever</h4> <button ng-click="add(1)" class="button">Add</button> <a ng-click="subtract(1)" class="button alert">Subtract</a> <h4>Current count: {{ count }}</h4> </div>

Both the button and the link will be bound to an action on the containing $scope, so when they are pressed (clicked), Angular will call the method. Note that when we are telling Angular what method to call, were putting it in a string with the parentheses. Now, lets create an action on our DemoController.
app.controller('DemoController', function($scope) { $scope.counter = 0; $scope.add = function(amount) { $scope.counter += amount; }; $scope.subtract = function(amount) { $scope.counter -= amount; }; });

See it
The simplest adding machine ever
Add Subtract

Current count: 1

Data binding and AJAX in our app


Interaction
As we saw in the last example of the previous section, we bound a button to the view using the data binding we just learned about. In that example, we bound the button to the play() action and bound the PlayerControllers method play on the play button (and the same for the stop button, with the stop method).

AJAX
In the last tutorial, we referenced a locally hosted audio file; however, doing so gives us a static NPR file instead of a live NPR feed. In our NPR app, well use $http to populate the list of available news clips we can play. Out of the box, AngularJS supports AJAX (or asynchronous JavaScript and XML). This support gives us the ability to make requests back and forth from a server or multiple servers, which is essential to a client-side app like ours that needs to get and set data. AngularJS supports AJAX through a service (which well discuss in an upcoming section) called the $http service. All of the core AngularJS services are prefixed with $. Weve seen this before with the $scope service. The $http service is incredibly flexible and gives us many different ways to call AJAX services. To keep this tutorial simple, were only going to focus on the simplest method possible. Well dive deeper into the $http service in a more advanced section in the future. Before we go too far into detail, lets make a request with the $http service:
$http({ method: 'JSONP', url: 'http://api.openbeerdatabase.com/v1/beers.json?callback=JSON_CALLBACK' }).success(function(data, status, headers, config) { // data contains the response // status is the HTTP status // headers is the header getter function // config is the object that was used to create the HTTP request }).error(function(data, status, headers, config) { });

Try it
Make request
Request result: []

The $http service is a core AngularJS service that helps faciliate communication with remote HTTP servers via the XMLHttpRequest object or through JSONP. Note that AngularJS will take care of handling a JSONP request if you append the EXACT string: callback=JSON_CALLBACKas just above. AngularJS will replace JSON_CALLBACK with the proper callback it constructs for you. The $http service is a function that takes a configuration object, which defines how the HTTP request is constructed. It will return a promise that has two methods success and error. To get a list of the available audio clips, lets make a request to NPRs API. First, youll need to register with NPR to get an API key. Head over to their site at http://www.npr.org/templates/reg/ or click here to register from this page. Keep note of your API key. Well use that in a minute. Now, were going to set up our PlayerController to call the $http service to fetch a list of the clips. Just like we did above, lets call the $http service to make a request, this time to get all the clips. We want this service to run when the controller is instantiated, so we can simply put this method right in the controller function (which is run when the controller is created), like so:
var apiKey = 'YOUR_KEY', nprUrl = 'http://api.npr.org/query?id=61&fields=relatedLink,title,byline,text,au dio,image,pullQuote,all&output=JSON';

app.controller('PlayerController', function($scope, $http) { // Hidden our previous section's content // construct our http request $http({ method: 'JSONP', url: nprUrl + '&apiKey=' + apiKey + '&callback=JSON_CALLBACK' }).success(function(data, status) { // Now we have a list of the stories (data.list.story) // in the data object that the NPR API // returns in JSON that looks like: // data: { "list": {

// // // //

"title": ... "story": [ { "id": ... "title": ...

}).error(function(data, status) { // Some error occurred }); });

Now that we have the the list of clips in data in the success function, we can bind it to the $scope object simply by storing the list on $scope in the success callback:
// from above }).success(function(data, status) { // Store the list of stories on the scope // from the NPR API response object (described above) $scope.programs = data.list.story; }).error(function(data, status) { // Some error occurred

Now, just like above, we can reference this data in our view simply by referencing programs in our view. Note that one of the benefits of using AngularJS is that it will automatically populate promises into your view when the promise resolves.
<div ng-controller="PlayerController"> {{ programs }} </div>

Try it
In the next section, well discuss how to display this data object in our view in a meaningful way using some built-in directives (and a little bit more).

The official repository for the beginner series is available as a git repo here: https://github.com/auser/ng-newsletter-beginner-series. To get this repo locally, ensure that you have git installed, clone the repo, and check out the part3 branch:
git clone https://github.com/auser/ng-newsletter-beginnerseries.git git checkout -b part3

Want to know when Part 4 and every article in this series is released? Sign up for ngnewsletter below.

Form validation with AngularJS


Client-side form validations are one of the coolest features inside of AngularJS. AngularJS form validation enables you to write a modern HTML5 form that is interactive and responsive from the start. There are many form validation directives available in AngularJS. Well talk about a few of the most popular ones here and then well get into how to build your own validations.
<form name="form"> <label name="email">Your email</label> <input type="email" name="email" ng-model="email" placeholder="Email Address" /> </form>

AngularJS makes it pretty easy for us to handle client-side form validations without adding a lot of extra effort. Although we cant depend on client-side validations keeping our web application secure, they provide instant feedback of the state of the form. To use form validations, we first must ensure that the form has a name associated with it, like in the above example. Got it? Great! All input fields can validate against some basic validations, like minimum length, maximum length, etc. These are all available on the new HTML5 attributes of a form. It is usually a great idea to use the novalidate flag on the form element. This will prevent the browser from submitting the form. Lets look at all the validation options we have that we can place on an input field:

Required
To validate that a form input has been filled out, simply add the html5 tag: required to the input field:
<input type="text" required />

Minimum length
To validate that a form input input is at least a {number} of characters, add the AngularJS directive ng-minlength="{number}"to the input field:
<input type="text" ng-minlength=5 />

Maximum length
To validate that a form input is equal to or less than a number of characters, add the AngularJS directiveng-maxlength="{number}":
<input type="text" ng-maxlength=20 />

Matches a pattern
To ensure that an input matches a regex pattern, use the AngularJS directive: ngpattern="/PATTERN/":
<input type="text" ng-pattern="/a-zA-Z/" />

Email
To validate an email address in an input field, simply set the input type to email, like so:
<input type="email" name="email" ng-model="user.email" />

Number
To validate an input field has a number, set the input type to number:
<input type="number" name="email" ng-model="user.age" />

Url
To validate that an input represents a url, set the input type to url:
<input type="url" name="homepage" ng-model="user.facebook_url" />

Custom validations
AngularJS makes it very easy to add your own validations as well by using directives. For instance, lets say that we want to validate that our username is available in the database. To do this, well implement a directive that fires an ajax request whenever the form changes:
var app = angular.module('validationExample', []);

app.directive('ensureUnique', ['$http', function($http) { return { require: 'ngModel', link: function(scope, ele, attrs, c) { scope.$watch(attrs.ngModel, function() { $http({ method: 'POST', url: '/api/check/' + attrs.ensureUnique, data: {'field': attrs.ensureUnique} }).success(function(data, status, headers, cfg) { c.$setValidity('unique', data.isUnique); }).error(function(data, status, headers, cfg) { c.$setValidity('unique', false); }); }); } } }]);

Control variables in forms


AngularJS makes properties available on the containing $scope object available to us as a result of setting a form inside the DOM. These enable us to react to the form in realtime (just like everything else in AngularJS). The properties that are available to us are:

Note that these properties are made available to us in the format:


formName.inputFieldName.property

Unmodified form
A boolean property that tells us if the user has modified the form. This is true if the user hasnt touched the form, and falseif they have:
formName.inputFieldName.$pristine;

Modified form
A boolean property if and only if the user has actually modified the form. This is set regardless of validations on the form:
formName.inputFieldName.$dirty

Valid form
A boolean property that tells us that the form is valid or not. If the form is currently valid, then this will be true:
formName.inputFieldName.$valid

Invalid form
A boolean property that tells us that the form is invalid. If the form is currently invalid, then this will be true:
formName.inputFieldName.$invalid

The last two properties are particularly useful for showing or hiding DOM elements. They are also very useful when setting a class on a particular form.

Errors
Another useful property that AngularJS makes available to us is the $error object. This object contains all of the validations on a particular form and if they are valid or invalid. To get access to this property, use the following syntax:
formName.inputfieldName.$error

If a validation fails then this property will be true, while if it is false, then the value has passed the input field.

A little style never hurts


When AngularJS is handling a form, it adds specific classes to the form based upon their state. These classes are named similar to the properties that we can check as well. These classes are:
.ng-pristine {} .ng-dirty {} .ng-valid {} .ng-invalid {}

The correspond to their counterpart on the particular input field. When a field is invalid, the .ng-invalid class will be applied to the field. This particular site sets the css class as: input.ng-invalid { border: 1px solid red; } input.ng-valid { border: 1px solid green; }

Putting it all together


Lets build a signup form. This signup form will include the persons name, their email, and a desired username. Lets start by looking at what the form will look like when its done. Go ahead, pla y with it, start typing in the input fields, see how the form responds and reacts. Notice that the submit button becomes disabled when the form goes invalid:
Signup form Your name Your email Username Submit

Lets start with defining the form:


<form name="signup_form" novalidate ng-submit="signupForm()"> <fieldset> <legend>Signup</legend>

<button type="submit" class="button radius">Submit</button> </fieldset> </form>

This forms name is signup_form and we are going to call signupForm() when the form is submitted. Now, lets add the name of the user:
<div class="row"> <div class="large-12 columns"> <label>Your name</label> <input type="text" placeholder="Name" name="name" ng-model="signup.name" ng-minlength=3 ng-maxlength=20 required /> </div> </div>

Try it
Your name

Breaking this down. First thing to note is that I use Foundation for my css layouts, so youll see that syntax is my forms. We added a form that has an input called name that is bound (by ng-model) to the object signup.name on the $scope object. We also setup a few validations. These validations say we have to have a minlength of our name of 3 or more characters. We also impose a maximum limit of characters of 20 characters (this will be invalid at 21 characters and higher). Lastly, werequire that the name be filled out for the form to be valid.

Lets use the properties to show and/or hide a list of errors if the form is invalid. Well also use the $dirty attribute to make sure the errors dont show up if the user hasnt touched the field:
<div class="row"> <div class="large-12 columns"> <label>Your name</label> <input type="text" placeholder="Name" name="name" ng-model="signup.name" ng-minlength=3 ng-maxlength=20 required /> <div class="error" ng-show="signup_form.name.$dirty && signup_form.name.$invalid"> <small class="error" ng-show="signup_form.name.$error.required"> Your name is required. </small> <small class="error" ng-show="signup_form.name.$error.minlength"> Your name is required to be at least 3 characters </small> <small class="error" ng-show="signup_form.name.$error.maxlength"> Your name cannot be longer than 20 characters </small> </div> </div>

</div>

Try it
Your name

Breaking this down, were only going to show our errors if the form is invalid and changed, just as before. This time, well look through each of the valiations and only show a particular DOM element if the particular validation property is invalid. Lets look at the next set of validations, the email validation:
<div class="row"> <div class="large-12 columns"> <label>Your email</label> <input type="email" placeholder="Email" name="email" ng-model="signup.email" ng-minlength=3 ng-maxlength=20 required /> <div class="error" ng-show="signup_form.email.$dirty && signup_form.email.$invalid"> <small class="error" ng-show="signup_form.email.$error.required"> Your email is required. </small> <small class="error" ng-show="signup_form.email.$error.minlength"> Your email is required to be at least 3 characters </small> <small class="error" ng-show="signup_form.email.$error.email">

That is not a valid email. Please input a valid email. </small> <small class="error" ng-show="signup_form.email.$error.maxlength"> Your email cannot be longer than 20 characters </small> </div> </div>

Try it
Your email

This time (with the entire form included), were looking at the email field. Note that we set the type of the input field to emailand added a validation error on $error.email. This is based off the AngularJS email validation (and the HTML5 attribute). Finally, lets look at our last input field, the username:
<div class="large-12 columns"> <label>Username</label> <input type="text" placeholder="Desired username" name="username" ng-model="signup.username" ng-minlength=3 ng-maxlength=20 ensure-unique="username" required /> <div class="error" ng-show="signup_form.username.$dirty && signup_form.username.$invalid">

<small class="error" ngshow="signup_form.username.$error.required">Please input a username</small> <small class="error" ngshow="signup_form.username.$error.minlength">Your username is required to be at least 3 characters</small> <small class="error" ngshow="signup_form.username.$error.maxlength">Your username cannot be longer than 20 characters</small> <small class="error" ngshow="signup_form.username.$error.unique">That username is taken, please try another</small> </div> </div>

Try it
Username

In our last field, were using all the same previous validations, with the exception that weve added our custom validation. This custom validation is defined using an AngularJS directive:
app.directive('ensureUnique', ['$http', function($http) { return { require: 'ngModel', link: function(scope, ele, attrs, c) { scope.$watch(attrs.ngModel, function() { $http({ method: 'POST', url: '/api/check/' + attrs.ensureUnique,

data: {'field': attrs.ensureUnique} }).success(function(data, status, headers, cfg) { c.$setValidity('unique', data.isUnique); }).error(function(data, status, headers, cfg) { c.$setValidity('unique', false); }); }); } } }]);

When the form input is valid, this will make a POST request check to the server at /api/check/username to check if the username is available. Now, obviously since were only talking about front-end code here, we dont have a backend to test this on, although it could easily be written. Update: As per a discussion in the comments, Ive added an update using the $timeout service. To check out that full source, check it out here. Lastly, putting our button together, we can use the angular directive ng-disabled to disable and reenable the button when the form is valid:
<button type="submit" ng-disabled="signup_form.$invalid" class="button radius">Submit</button>

As we said above, the form itself will have a $invalid and valid attributes given to us for free. Update 2: Although live validation is great, it can be abrasive to the user when they see errors pop-up while they are typing, long before they have put in a valid value. You can be nicer to your users if you show the validations either only after they have submitted the form or after they have moved off of the input. Lets look at both ways to do that.

Show validations after submit


To show validations only after the user has attempted to submit the form, you can capture a submitted value on the scope and check for that scope to show the error.

For instance, lets take a look at the first example and only show the errors when the form has been submitted. On theng-show directive on for the form input, we can add a check to see if the form has been submitted (which we will implement shortly):
<form name="signup_form" novalidate ng-submit="signupForm()"> <fieldset> <legend>Signup</legend> <div class="row"> <div class="large-12 columns"> <label>Your name</label> <input type="text" placeholder="Name" name="name" ng-model="signup.name" ng-minlength=3 ng-maxlength=20 required /> <div class="error" ng-show="signup_form.name.$dirty && signup_form.name.$invalid && signup_form.submitted"> <small class="error" ng-show="signup_form.name.$error.required"> Your name is required. </small> <small class="error" ng-show="signup_form.name.$error.minlength"> Your name is required to be at least 3 characters

</small> <small class="error" ng-show="signup_form.name.$error.maxlength"> Your name cannot be longer than 20 characters </small> </div> </div> </div> <button type="submit" class="button radius">Submit</button> </fieldset> </form>

Now, the error div will only show up if the signup_form.submitted variable has been set to true. We can implement this in thesignupForm action, like so:
app.controller('signupController', ['$scope', function($scope) { $scope.submitted = false; $scope.signupForm = function() { if ($scope.signup_form.$valid) { // Submit as normal } else { $scope.signup_form.submitted = true; } } }]);

Now, when your users try to submit the form while there is an invalid element, you can catch it and show them the appropriate errors.

Show validations only after blur


If you want to retain the real-time nature of the error input, you can show your users the errors after they have blurred off of the input form. To do this, we like to add a small directive that will attach a new variable to the form. The directive we like to use is the ngFocus directive and it looks like:
app.directive('ngFocus', [function() { var FOCUS_CLASS = "ng-focused"; return { restrict: 'A', require: 'ngModel', link: function(scope, element, attrs, ctrl) { ctrl.$focused = false; element.bind('focus', function(evt) { element.addClass(FOCUS_CLASS); scope.$apply(function() {ctrl.$focused = true;}); }).bind('blur', function(evt) { element.removeClass(FOCUS_CLASS); scope.$apply(function() {ctrl.$focused = false;}); }); } } }]);

To implement the ngFocus directive, we can simply attach this directive to the input element, like so:
<input ng-class="{error: signup_form.name.$dirty && signup_form.name.$invalid}" type="text" placeholder="Name" name="name" ng-model="signup.name" ng-minlength=3 ng-maxlength=20 required ng-focus />

The ngFocus directive simply attaches an action to the blur and focus events on the form input and adds a class (ng-focused) and sets the form input field $focused as true. Then you can show your individual error messages depending if the form is focused or not. For instance:
<div class="error" ng-show="signup_form.name.$dirty && signup_form.name.$invalid && !signup_form.name.$focused">

I hope this post shows you how cool AngularJS form validation can be. Stay tuned for the next post and sign-up for the newsletter for weekly, up-to-date posts about the latest and greatest, curated angularjs news.

Build custom directives with AngularJS


Most everything we use in AngularJS is a directive. Directives are what makes AngularJS so powerful and responsive. Directives are the root of AngularJS and how we as developers interact with AngularJS. Although AngularJS is packed with powerful directives out of the box, often times we want to create our own reusable functionality. In this post, well focus on how to tackle the seemingly complex process of creating directives. Well start with building simple directives and explain the process throughout the post. To start making your own directive, lets first understand what directives actually are. Directives, in AngularJS are, at their core functions that get run when the DOM is compiled by the compiler. Using this powerful concept, AngularJS enables us to create new directives that we can encapsulate and simplify DOM manipulation. We can create directives that modify or even create totally new behavior in HTML. If youve ever used any part of AngularJS before, youve used a directive, whether you know it or not. The ng-app attribute is a directive, so is ng-controller and all of the ng- prefixed attributes.
<body ng-app> <input type="text" ng-model="name" placeholder="name">

<h1>{{ name }}</h1> </body>

Try it
Type Hello Ari Lerner

When AngularJS loads this simple example, it will traverse the DOM elements looking for any directives that are associated with each DOM element. Once its found all of them (if there are multiple directives), it will then start running the directive and associating it with the DOM element. This all happens behind the scenes and automatically for you. To invoke a directive from HTML, we simply can apply the directive in the DOM. That is to say, we pick one of the four methods for invoking a directive:

As an attribute:
<span my-directive></span>

As a class:
<span class="my-directive: expression;"></span>

As an element:
<my-directive></my-directive>

As a comment:
<!-- directive: my-directive expression -->

These are the same in the eyes of AngularJS. In fact, AngularJS even gives you other options for invoking directives with name prefixes. These are all equivalent, as well:
<input type="text" ng-model="directivename" placeholder="name" /> <span ng-bind="directivename"></span> <span ng:bind="directivename"></span> <span ng_bind="directivename"></span> <span x-ng-bind="directivename"></span> <span data-ng-bind="directivename"></span>

Try it
ng-bind=directivename: ng:bind=directivename: ng_bind=directivename: x-ng-bind=directivename: data-ng-bind=directivename:

The last two are are the only methods of invoking directives that are HTML5 compliant and that will pass HTML5 validators.

Building our first directive


Although well discuss in greater detail how directives actually work at the fundamental level later, lets start by creating our first directive. Well be walking through creating a sparkline directive that will show the weather forecast for the next few days based onopenweathermap data. We will be building this directive:

Weather for San Francisco


020406080

Our first, basic directive looks like this:


app.directive('ngSparkline', function() { return { restrict: 'A', template: '<div class="sparkline"></div>' } });

And then well invoke it in our html:


<div ng-sparkline></div>

Notice that when we invoke it, the name of the directive is not the same as when we define it (ngSparkline vs. ng-sparkline). This is because AngularJS will handle translating the camel cased name when we define it to the snake case when we invoke it.

Although our first example doesnt do very much (yet), it already is showing some powerful features. Anywhere in our html, we can add the attribute ng-sparkline and have the template be appended to the DOM element. There are two ways to build a directive. In our example, were using the method of returning a directive description object. AngularJS expects either one of these objects or a link function when were creating a directive. Building a directive with the link function is usually enough for relatively simple directives. For the most part, well be creating directives using the description object.

Restrict option
In our examples description object, were setting two config components. First, were setting the restrict config option. The restrict option is used to specify how a directive can be invoked on the page. As we saw before, there are four different ways to invoke a directive, so there are four valid options for restrict:
'A' - <span ng-sparkline></span> 'E' - <ng-sparkline></ng-sparkline> 'C' - <span class="ng-sparkline"></span> 'M' - <!-- directive: ng-sparkline -->

The restrict option can specify multiple options, as well. If you want to support more than one as an element or an attribute, simply make sure all are specified in the restrict keyword:
restrict: 'EA'

Template
Secondly, in our example were also setting a template. This template is an inline template where we are specifying the html that will be appended (or replaced, well discuss this shortly). This is particularly useful when we want to share directives across apps and you only want to pass a single file around.

TemplateUrl
If you prefer to load a template over ajax, you can specify the templateUrl option, which will use ajax to pull the template.
templateUrl: 'templates/ng-sparkline-template.html'

With that, we can start adding functionality. Before we can jump straight into that, we need to look at how the directive is instantiated in the DOM.

How directives are born (compilation and instantiation)


When the DOM is done loading and the AngularJS process starts booting up, the first process that happens is the HTML is parsed by the browser as a DOM tree. This tree is then parsed using AngularJSs $compile() method. $compile runs through the DOM tree and looks for directive declarations for the different DOM elements. Once all directive declarations are found for each DOM element and sorted (by priority, which well get into shortly), the directives compile function is run and is expected to return a link() function. The $compile() function will return a linking function that wraps all of the containing DOM elements directives' linking functions. Finally, the linking function is invoked with the containing scope that attaches all of the associated directives to that scope. This is where well do most of the work when building directives, as this is where we can register listeners, set up watches, and add functionality. The result of this process is why the live data-binding exists between the scope and the DOM tree.

Why have a compile and link function?


So why does AngularJS have two functions that run at the compile phase instead of just combining them into one? Boiled down, the answer is for performance. Its slow to compile and interpolate against scopes every time a new directive of the same type is created. Because of this, all of the slow parts of the compilation process are front-loaded into the compile phase, while the linking happens when everything is associated and attached to the DOM.

In summary
Well use the compile function to both manipulate the DOM before its rendered and return a link function (that will handle the linking for us). This also is the place to put any methods that need to be shared around with all of the instances of this directive. Well use the link function to register all listeners on a specific DOM element (thats cloned from the template) and set up our bindings to the page.

Back to ngSparkline
Our sparkline graph will need to do a little more than show us a div on the page to actually be useful. To do that, well have to bind a controller input on the directive. Basically, well want the directive to be driven by the input of another directive. In most cases, well want to bind our directive to the ng-model directives controller.

Require option
Well enforce that we need this dependency by setting the require option:
app.directive('ngSparkline', function() {

return { restrict: 'A', require: '^ngModel', template: '<div class="sparkline"><h4>Weather for {{ngModel}}</h4></div>' } });

Now, if we invoke the directive on the page without the ng-model directive, our browser will complain and throw an error. To invoke our directive now, we simply have to add the ngmodel directive:
<input type="text" ng-model="city" placeholder="Enter a city" /> <div ng-sparkline ng-model="city"></div>

Notice, in the require option, we prefixed the controller with a ^. AngularJS gives you two options in the require option about how to declare requirements with a prefixed character:
^ -- Look for the controller on parent elements, not just on the local scope ? -- Don't raise an error if the controller isn't found

Scope
Just like in every other part of AngularJS DOM control, directives can be given their own scopes. This is important to note, because without declaring an isolated scope from the rest of the DOM, our directive could muck with the local controller scope and cause unexpected behavior. To get around this trouble, AngularJS gives you the ability to isolate the scope of the directive from the rest of the page using the scope option.
app.directive('ngSparkline', function() { return { restrict: 'A', require: '^ngModel', scope: { ngModel: '='

}, template: '<div class="sparkline"><h4>Weather for {{ngModel}}</h4></div>' } });

The scope option can take one of two different options. It can be set to true (its false by default).
scope: true,

When the scope directive is set to true, a new scope will be created for the directive. While its useful to ensure that a new scope will be created for the directive, that scope will still participate in the normal controller-scope hierarchical relationship. We can isolate the directives scope outside of the parent relationship by creating an isolate scope. An isolate scope does not prototypically inherit from the parent scope, but creates an entirely new one. Creating this isolatescope will ensure that your directive does not mess with the existing scope. To create an isolate scope, simply pass an object back in the scope option:
scope: {}

This will create an empty scope. This is not particularly useful because your directive will have nothing available on its scope (other than the variables that you manually add). To make local variables on your local scope available to the new directives scope, youll have to pass one of the following three aliases in the object:

Local scope property


Binding a local scope (string) to the value of the DOM attribute, use the @ symbol. Now the value of the outer scope will be available inside your directives scope:
@ (or @attr)

Bi-directional binding
A bi-directional binding can be set up between the local scope property and the parent property using the = symbol. If the parent model changes, just like in normal data-binding then the local property will reflect the change.
= (or =attr)

Parent execution binding


To execute a function in the context of the parent scope, we can bind a function using the & symbol. This is to say that when setting the value, a function wrapper will be created and point to the parent function. To call the parent method with an argument, youll need to pass an object with the key being the name of the argument and the value being the argument to pass:
& (or &attr)

For example, if were writing an email client and we are creating an email textbox such as:
<input type="text" ng-click="sendMail()" /> <!-- Invoke the directive --> <div scope-example ng-model="to" on-send="sendMail(email)" fromname="ari@fullstack.io" />

We have a model, a function, and a string. To get access to these on your directives scope:
scope: { ngModel: '=', onSend: '&', fromName: '@' }

Try it
Send

ngModel: onSend (status): Not sent fromName: ari@fullstack.io

Show controller source Going back to our sparkline directive, well need to pass in a city with our directive from which we want to pull the weather from openweathermap. To do this, well start out by setting it statically on the directive by passing it in as an attribute:
<div ng-sparkline ng-model="San Francisco"></div>

Our directive now looks like this:


app.directive('ngSparkline', function() { return { restrict: 'A', require: '^ngModel', scope: { ngCity: '@' }, template: '<div class="sparkline"><h4>Weather for {{ngModel}}</h4></div>' } });

If we want to be more explicit and descriptive about what model we are requiring, we can change the require: '^ngModel'above to be require: '^ngCity'. This comes in handy when you are communicating requirements on a team or you want to reuse the directive in another project. The implementation would change to the more explicit version:
<div ng-sparkline ng-city="San Francisco"></div>

If we want to support this method of setting ng-city instead of ngModel, well have to add some supporting logic. As we said above, the require option will inject the controller of the require option. For ngCity to work, well have to create a custom directive with a controller defined. This is as simple as:
app.directive('ngCity', function() { return { controller: function($scope) {} }

});

Alternatively, you can continue to use ngModel.

Pulling weather data


Now that we have the city, we can use openweathermap to grab the latest weather data. In order to do this, well have to set up a function that will run when the directive is linked to the DOM. If we write this function in the compile method, then well modify the DOM in place.
app.directive('ngSparkline', function() { return { restrict: 'A', require: '^ngCity', scope: { ngCity: '@' }, template: '<div class="sparkline"><h4>Weather for {{ngCity}}</h4></div>', link: function(scope, iElement, iAttrs) { // get weather details } } });

The link function will be run as soon as the directive is linked to the DOM. In order to call out to a separate service, however, well have to inject the $http service. Because of this, well need to define a controller to get access to the service.

Controller option
In a directive, when we set the controller option we are creating a controller for the directive. This controller is instantiated before the pre-linking phase. The pre-linking and post-linking phases are executed by the compiler. The pre-link function is executed before the child elements are linked, while the post-link function is executed after. It is only safe to do DOM transformations after the post-link function. We are defining a controller function in our directive, so we dont need to define either of these functions, but it is important to note that we cannot do DOM manipulations in our controller function. What does a controller function look like? Just like any other controller. Well inject the $http service in our controller (using the bracket injection notation):
app.directive('ngSparkline', function() { return { restrict: 'A', require: '^ngCity', scope: { ngCity: '@' }, template: '<div class="sparkline"><h4>Weather for {{ngCity}}</h4></div>', controller: ['$scope', '$http', function($scope, $http) { $scope.getTemp = function(city) {} }], link: function(scope, iElement, iAttrs, ctrl) { scope.getTemp(iAttrs.ngCity); } }

});

Note that in our link function, we have access to all of the attributes that were declared in the DOM element. This will become important in a minute when we go to customize the directive. Now we can create the function getTemp to fetch from the openweathermap.
var url = "http://api.openweathermap.org/data/2.5/forecast/daily?mode=json&units= imperial&cnt=7&callback=JSON_CALLBACK&q="

$scope.getTemp = function(city) { $http({ method: 'JSONP', url: url + city }).success(function(data) { var weather = []; angular.forEach(data.list, function(value){ weather.push(value); }); $scope.weather = weather; }); }

Now, inside of our link function, well have a promise that will be fulfilled by the controller method. A promise, if youre not familiar, is basically an object that will return the result of an action that is run asynchronously.
<div ng-sparkline ng-city="San Francisco"></div>

See it
This will print out a bunch of JSON

Weather for San Francisco


Weather:
[{"dt":1376078400,"temp":{"day":57.81,"min":57.81,"max":57.81,"night":57.81,"eve":57.81,"morn":5 7.81},"pressure":1021.65,"humidity":99,"weather":[{"id":804,"main":"Clouds","description":"overc ast clouds","icon":"04n"}],"speed":6.05,"deg":228,"clouds":92},{"dt":1376164800,"temp":{"day":64.09, "min":56.35,"max":64.09,"night":56.35,"eve":59.36,"morn":57.25},"pressure":1022.84,"humidity":87 ,"weather":[{"id":500,"main":"Rain","description":"light rain","icon":"10d"}],"speed":5.77,"deg":241,"clouds":0,"rain":0.5},{"dt":1376251200,"temp":{"day ":64.45,"min":55.22,"max":64.56,"night":55.22,"eve":60.71,"morn":56.25},"pressure":1021.66,"humi dity":87,"weather":[{"id":800,"main":"Clear","description":"sky is clear","icon":"01d"}],"speed":5.31,"deg":231,"clouds":0}]

As you can see, the directive is rendered on screen initially without data, but as soon as the link method is run (linking the specific element to the DOM), the getTemp method will run and will eventually populate the weather property on the scope. Now, lets take this data and create a sparkline with it. To start, well want to pick a property on the weather to work on. Lets start by creating a chart on the high temperatures. To start with, well need to create a $watch on the weather object. Because we are fetching the weather data asynchronously, we cannot simply write the method expecting the data to be populated for us when the linking function runs. No matter, AngularJS makes this incredibly easy with the built-in function$watch. The $watch function will register a callback to be executed whenever the result of the expression changes. Inside the $digestloop, every time AngularJS detects a change, it will call this function. This has the side effect that we cannot depend on state inside this function. To counter this, well check for the value before we depend on it being in place. Here is our new $watch function:
scope.getTemp(iAttrs.ngCity); scope.$watch('weather', function(newVal) { if (newVal) {

} });

Every time the weather property on our scope changes, our function will fire. We will use d3 to chart our sparkline. Heres what we have so far:
app.directive('ngSparkline', function() { var url = "http://api.openweathermap.org/data/2.5/forecast/daily?mode=json&units= imperial&cnt=14&callback=JSON_CALLBACK&q="; return { restrict: 'A', require: '^ngCity', scope: { ngCity: '@' }, template: '<div class="sparkline"><h4>Weather for {{ngCity}}</h4><div class="graph"></div></div>', controller: ['$scope', '$http', function($scope, $http) { $scope.getTemp = function(city) { $http({ method: 'JSONP', url: url + city }).success(function(data) { var weather = []; angular.forEach(data.list, function(value){

weather.push(value); }); $scope.weather = weather; }); } }], link: function(scope, iElement, iAttrs, ctrl) { scope.getTemp(iAttrs.ngCity); scope.$watch('weather', function(newVal) { // the `$watch` function will fire even if the // weather property is undefined, so we'll // check for it if (newVal) { var highs = [], width height = 200, = 80;

angular.forEach(scope.weather, function(value){ highs.push(value.temp.max); }); // chart } });

} } });

See it
Weather for San Francisco
020406080

Show d3 source Now that we have our chart being drawn, lets look at ways that we can customize the directive when we invoke it. Inside of our watch function, were currently setting a static height and width. We can do better than that by allowing the invocation to determine the width and the height. Because we have access to the iAttrs (the instance of the attributes on the instance of the DOM element), we can simply look there first; otherwise we can set a default. Change the width and the height to look like this:
var width height = iAttrs.width || 200, = iAttrs.height || 80;

When we invoke the directive, this time we can add a width to set the width:
<div ng-sparkline width='400'></div>

Now our sparkline changes width to be 400 pixels, instead of the default 200.

See it
Weather for San Francisco
020406080

Inside of our directive as it stands today, we have a label that tells us Weather for . Although this is convenient for demo purposes, we might not always want that label to be static inside the directive. We can set it to include any html that we put inside of the DOM element that contains our directive.

Transclude option
Although the name sounds complex, transclusion refers to compiling the content of the element and making the source available to the directive. The transcluded function is prebound to the calling scope, so it has access to the current calling scope. Looking at an example, lets change the invocation to:
<div ng-sparkline ng-city="San Francisco" width='400'> <h3>A custom view of the weather in San Francisco</h3> </div>

To get this to show up in our template, well need to use a special directive called ngTransclude. This is how the template knows where to place the custom HTML. Lets modify the template in our directive to include the custom content:
template: '<div class="sparkline"><div ng-transclude></div><div class="graph"></div></div>'

Additionally, well have to tell AngularJS that our directive will be using transclusion. To do that, well have to set the transclude option either to:

true, which will take the content of the directive and place it in the template element, which will take the entire defined element including the lower priority directives.

Set the transclude option to true, as we only want the content of our directive to show up in our template:
transclude: true

See it
A custom view of the weather in San Francisco
020406080

Replace option
Sometimes it is better to replace the entire DOM object, rather than append the new template to it. AngularJS makes this easy to accomplish by simply adding replace option in the directive description object. Set the replace option to true, like so:
replace: true

Priority option
Directives on elements are compiled in a sorted order based on priority. Sometimes it matters what ordered directives are applied. By setting a higher priority, you can almost guarantee the order in which the directives are applied. To set a higher priority of one directive over another, simply add the priority option and set it to a numerical value higher than 0 (the default):
priority: 10

Terminal option
Sometimes its useful to stop the execution of the compiler for including other directives. This is most useful when used in conjunction with setting the priority. terminal will stop the execution of any directives at a lower priority than this one.
terminal: true

Next steps
Weve covered how to build a directive from the very low-level to the top. Hopefully youve gained some confidence and knowledge about how to move forward in the future and provide and build your own custom directives.
app.directive('ngSparkline', function() { var url = "http://api.openweathermap.org/data/2.5/forecast/daily?mode=json&units= imperial&cnt=14&callback=JSON_CALLBACK&q="; return { restrict: 'A', require: '^ngCity', transclude: true, scope: { ngCity: '@' }, template: '<div class="sparkline"><div ng-transclude></div><div class="graph"></div></div>', controller: ['$scope', '$http', function($scope, $http) { $scope.getTemp = function(city) {

$http({ method: 'JSONP', url: url + city }).success(function(data) { var weather = []; angular.forEach(data.list, function(value){ weather.push(value); }); $scope.weather = weather; }); } }], link: function(scope, iElement, iAttrs, ctrl) { scope.getTemp(iAttrs.ngCity); scope.$watch('weather', function(newVal) { // the `$watch` function will fire even if the // weather property is undefined, so we'll // check for it if (newVal) { var highs = [];

angular.forEach(scope.weather, function(value){ highs.push(value.temp.max); });

chartGraph(iElement, highs, iAttrs); }

}); } } });

var chartGraph = function(element, data, opts) { var width = opts.width || 200, height = opts.height || 80, padding = opts.padding || 30;

// chart var svg = d3.select(element[0]) .append('svg:svg') .attr('width', width) .attr('height', height) .attr('class', 'sparkline') .append('g') .attr('transform', 'translate('+padding+', '+padding+')');

svg.selectAll('*').remove();

var maxY x

= d3.max(data), = d3.scale.linear() .domain([0, data.length]) .range([0, width]),

= d3.scale.linear() .domain([0, maxY])

.range([height, 0]), yAxis = d3.svg.axis().scale(y) .orient('left') .ticks(5);

svg.append('g') .attr('class', 'axis') .call(yAxis);

var line

= d3.svg.line() .interpolate('linear') .x(function(d,i){return x(i);}) .y(function(d,i){return y(d);}),

path

= svg.append('svg:path') .data([data]) .attr('d', line) .attr('fill', 'none') .attr('stroke-width', '1');

app.directive('ngCity', function() { return { controller: function($scope) {} } });

Small ToDo List


<!DOCTYPE HTML> <html ng-app> <head> <script src="angular.min.js"></script> </head> <body> <form name="form" ng-controller="Foo"> <h2>{{tasks.length}} Tasks</h2> <p> <input type="text" ng-model="newTask"/> <button ng-click="addTask()">Add</button> </p> <ul> <li ng-repeat="(index, task) in tasks"> {{task}} <button ng-click="removeTask(index)">X</button> </li> </ul> </form> <script> function Foo($scope){ $scope.tasks = []; $scope.addTask = function() { $scope.tasks.push($scope.newTask); $scope.newTask = null; }; $scope.removeTask = function (index) { $scope.tasks.splice(index, 1); }; } </script> </body> </html>

Angular provides $http (AJAX) $resource (Even easier for REST backends)

Brief Introduction to Model-View-Controller in AngularJS

Previous Chapter Next Chapter


This chapter will be a work in progress for the next few days.

So far we have learned how to a basic program using Expressions in AnguarJS. In this chapter we will see how can you read and store values associated with various HTML elements (like input box <input/> , select item <select> ) in a JavaScript object/variable/anything without worrying about reading/setting it from/on DOM. We will also see what Model-View-Controller or MVC is? and how does AngularJS framework forces(for betterment) MVC on programmers. The reason the title of the chapter points to MVC is that we will achieve our goal of creating a GUI and reading the values of HTML elements using code which is written using Angular's forced MVC.

View

What represents a view in a website or a web application? The answer is simple: HTML. HTML content is what users/visitors see on a website. A little beautification with CSS is needed though. In AngularJS world the definition of a view has not changed, it is still the HTML content. Let us imagine that we are building a GUI for stock market information website. For simplicity we will keep just 3 components in our GUI:

1. Dropdown to select a company whose stock prices are to be checked and 2. a label to show the stock price.

Stock price = 200$ Input box for users to register their email id for subscribing to stock market email digests.

Sub scribe

That's it. That makes our view in AngularJS application. Trivial! isn't it?

Controller

The piece of code which will read the email id from input box when user clicks on subscribe or the piece of code which will show the stock price for a company when a company is selected from the dropdown is called a controller. A controller in AngularJS is a JavaScript function. The controller function is defined by application programmers/us and is automatically called by AngularJS whenever the HTML(view)

is loaded in the DOM tree. Remember that it is not automatically called when HTML(view) is rendered but when HTML is parsed and loaded in DOM tree.

function stockController($scope){ //Don't worry about the parameter name '$cope'. $ is allowed as part of variable name //Code to handle changes in view/code to change view here. //Going ahead we will also write the code in JQuery and compare it with AngularJS }

You must be wondering about what $scope is and why is it needed as a parameter to the function which is defined by you as a programmer. Well $scope is a JavaScript object passed by AngularJS and it supposed to be used by the programmer as a binder between view and controller. We had discussed in the chapter 1.1 that AngularJS obviates the task of writing data binding code between UI and JavaScript and $scope helps in that. The next section explains the role $scope plays.

Model

Model represents the current state of the view. For changing the stock market price label dynamically, the controller changes the model. In AngularJS a model is a property of the $scope object. e.g. $scope.stockPrice="200$" . Similarly we can assign $scope.subscribeEmailId (which can be any name and not just subscribeEmailId) as a model for email Id input box. The special thing about this approach is that if we type email Id in input box, the $scope.subscribeEmailId variable is auto filled with the value you typed and vice versa if you change variable value from code, the changes are reflected in the GUI.
Let me remind you that you should not get confused by '$'. $ is used to differentiate Angular variable names. Good programming practice to help you distinguish your variable names from Angular's :).

Now the question that would have arose in your mind is how can just by changing the value of variable the view is changed. We will discuss the internals a bit later but for now lets see how to achieve it from code. Remember we talked about Angular directives and Angular Expressions in previous chapter. The model variable can be used in HTML(View) as a value of an Angular directive or in Angular expression. e.g. HTML <p ng-controller="stockCtrl" > {{ 'Stock price = ' + stockPrice }} </p> and corresponding JS code to change it.

function stockCtrl($scope){ $scope.stockPrice = "200$"; //It will replace the stockPrice variable in HTML Angular expression with the string "200$" }

Example code for understanding Model-View-Controller in AngularJS


Here is the link to the source code. Below is the output of the program shown in an iframe. It may take bit extra time to load if your internet connection is slow. You can see output of the program by clicking on . Explanation of the code here.

Console output for the above program.

Explanation of the code

Let us understand the code step by step. We had discussed about directives in Angular earlier. Lets get introduced to some new directives and the expression which we have used in our example.

ng-app : Role discussed here ng-controller="myController"

We have above learned the concept of a controller and we have seen how a controller function looks like. But to link a controller function with the view one has to use the directive ng-controller . This directive can be used on any DOM element as an attribute. Like any non boolean attribute one has to specify a value for it as well. The value we specified was "myController" . It tells angular that the controller

for the DOM element has the name myController and children DOM elements will have the same controller for them unless explicitly a new controller is specified for them using ng-controller . We have also learned that controller is a JavaScript function. So if you check the JavaScript code you will find a function with the name myController there. Don't worry about the code written in that controller, we will discuss that as well. Now this controller is called when the DOM tree is created. To prove that we have added two console.log() statements in our code. The log statement inside the controller gets printed first and the log statement inside the onload function(DOM rendered callback) gets printed second. You can check it right now by opening a debugger in your browser. If you don't have one you can see the image attached above for proof. Now let us see how this controller serves its purpose of changing DOM without making the programmer worry about exact DOM elements.

{{ selectedCompany + ' Stock price =' + stockPrice[selectedCompany] }}

We have learned that the controller function is passed a special parameter $scope by Angular. This serves the purpose of binding between controller and view. Now in our controller code we have added a new property to the $scope parameter: $scope.selectedCompany = "VMWare"; . This initializes the value of selectedCompany . So in our expression in HTML Code, the variable selectedCompany is replaced with "VMWare". Simple! the programmer didn't had to bother about the location of the DOM element. Also we have initialized the stockPrice object in our controller with three key value pairs, each for Google, Microsoft and VMWare. Since selectedCompany is initialized as "VMWare", stockPrice["VMWare"] will give you its stock price, which is 500$. Hence the stockPrice[selectedCompany] is replaced with 500$.

ng-model="selectedCompany"

This is a very important directive and is a special one. on't get bewildered by new
directives, they are the powerhouses of Angular and one cannot escape them. One also needs to learn the behaviour exhibited by various directives to use Angular. Coming back to ng-model ,

it should be used on HTML elements where you can change the value of HTML element using GUI. e.g. <input> box or <select> item. The value of this directive/attribute points to a variable specified as property of $scope in controller. For e.g. our select item has this attribute with value "selectedCompany" . Since we have initialized $scope.selectedCompany = "VMWare"; the select item's value is auto changed to "VMWare". The special thing about ng-model is that not only changes made through controller are available to GUI but also the changes made by GUI are auto reflected in $scope.selectedCompany in the controller. Also every GUI component/expression referring to "selectedCompany" gets updated. e.g. our expression gets updated with changes in select item.

To give the proof that changes made in GUI are auto reflected in controller we have associated ng-model with an input box.
<input ng-model="emailId" type="text"/>

Any text typed in the input box is auto stored in $scope.emailId . So when a user clicks on subscribe button, the controller need not search for the input box in DOM and read its value. Its there with it in the variable $scope.emailId . Controller code can just use it directly. That brings end to this special chapter. In the coming chapters we will learn more concepts of AngularJS

A RESTful Client with Angular.js


Posted on March 4, 2013 by ijason 3 Comments

In my last post, I showed you how how to create a RESTful API in PHP. In this post, Ill show you how to implement that API using Angular.js. Angular.js is a JavaScript framework developed by Google, designed to make your front-end development as easy as possible. Angular follows the MVC (model-view-controller) pattern of software development and encourages loose coupling between presentation, data, and logic components. To utilize my PHP API, Im going to use $http service in Angular. The $http service is a core Angular service that facilitates communication with the remote HTTP servers via browsers XMLHttpRequest object or via JSONP. The first thing Ill do is build my controller which Ill call AppsController.js. Controller AppsController.js
function AppListCtrl($scope, $http, $templateCache) { $scope.listApps = function() { $http({method: 'GET', url: './api.php?action=get_app_list', cache: $templateCache}). success(function(data, status, headers, config) { $scope.apps = data; //set view model $scope.view = './Partials/list.html'; //set to list view }). error(function(data, status, headers, config) { $scope.apps = data || "Request failed"; $scope.status = status; $scope.view = './Partials/list.html'; }); } $scope.showApp = function(id) { $http({method: 'GET', url: './api.php?action=get_app&id=' + id, cache: $templateCache}). success(function(data, status, headers, config) { $scope.appDetail = data; //set view model $scope.view = './Partials/detail.html'; //set to detail view

}). error(function(data, status, headers, config) { $scope.appDetail = data || "Request failed"; $scope.status = status; $scope.view = './Partials/detail.html'; }); } $scope.view = './Partials//list.html'; //set default view $scope.listApps(); } AppListCtrl.$inject = ['$scope', '$http', '$templateCache'];

The $http service uses the GET request to retrieve the JSON object from the server, in this case api.php. The data returned is used to fill the view model object. $scope.view sets the partial view to render. Lets take a look at the partial views. Partial Views list.html
<ul> <li ng-repeat="app in apps"> <a href="" ng-click="showApp(app.id)">{{app.name}}</a> </li> </ul>

The list partial view loops through the view model and displays the app names. ng-repeat="app
in apps" is similar to a For Each loop in .NET. The ng-click event calls

the showApp function in the controller. It accepts one parameter, the id, and uses a GET request to retrieve the app data. The appDetail view model for the detail partial view is populated and the partial view is rendered. detail.html
<table> <tr> <td>App Name: </td><td>{{appDetail.app_name}}</td> </tr> <tr> <td>Price: </td><td>{{appDetail.app_price}}</td> </tr> <tr> <td>Version: </td><td>{{appDetail.app_version}}</td> </tr> </table> <br /> <a href="" ng-click="listApps()">Return to the app list</a>

The detail partial view displays the data stored in the appDetail view model. Main View index.html
<html ng-app> <script src="./JS/angular.min.js"></script> <script src="./JS/AppsController.js"></script>

<body ng-controller="AppListCtrl"> <ng-include src="view"></ng-include> </body> </html>

In the main view, ng-include fetches, compiles and includes an external HTML fragment. As you can see creating a REST client with Angular.js can be short and simple. For a higher level of abstraction, Id recommend you check out the $resource service.

AngularJS Example Using a Java RESTful Web Service


JUL 13TH, 2013

AngularJS is the current MVV-Whatever JavaScript framework by Google. Among other things, it provides bidirectional data binding. Although Im neither a Java nor a JavaScript expert, I choose the following scenario for my Hello-World example: 1. Java backend provides a RESTful web service. 2. AngularJS consumes the web service. Thats it.

Project structure
I intentionally put the backend and frontend code in the same project to simplify the example. In a real project you probably want to have seperate projects for front- and backend.
1+---------------------------------------------------+ 2| demo project 3| 4| +----------------+ | +---------------+ | |

5| | backend (Java) | < -(REST)- > | frontend (JS) | | 6| +----------------+ 7| +---------------+ | |

8+---------------------------------------------------+

Since the backend is Java based, I used a Maven default structure ( mavenarchetype-site-simple ):
project structure 1 _documentation 2 readme.txt 3 ngdemo.iml 4 pom.xml 5 src 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 main java ngdemo domain User.java rest UserRestService.java service UserService.java css app.css img index-async.html index.html index.jsp js app.js controllers.js directives.js filters.js services.js lib angular angular-cookies.js angular-cookies.min.js angular.js angular-loader.js angular-loader.min.js

webapp

35 36 37 38 39 40 41 42 43 44

angular.min.js angular-resource.js angular-resource.min.js angular-sanitize.js angular-sanitize.min.js version.txt

partials partial1.html WEB-INF web.xml

src/main/java

is the backend. is the frontend. also includes a copy of angular-seed.

src/main/webapp/js src/main/webapp/

RESTful web service (backend)


Jersey is the Java reference implementation for providing REST. Install the following dependencies in your pom.xml :
pom.xml 1<!-- .. --> 2<!-- RESTful web service: Jersey --> 3<dependency> 4 5 6 <groupId>com.sun.jersey</groupId> <artifactId>jersey-server</artifactId> <version>1.17.1</version>

7</dependency> 8<dependency> 9 10 11 <groupId>com.sun.jersey</groupId> <artifactId>jersey-servlet</artifactId> <version>1.17.1</version>

12</dependency> 13<dependency> 14 15 16 <groupId>com.sun.jersey</groupId> <artifactId>jersey-json</artifactId> <version>1.17.1</version>

17</dependency>

18<!-- .. -->

Add the following servlet snippet to your web.xml :


web.xml 1<!-- .. --> 2<servlet> 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <load-on-startup>1</load-on-startup> <init-param> <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>com.sun.jersey.config.property.packages</param-name> <param-value>ngdemo.rest</param-value> </init-param> <servlet-class> com.sun.jersey.spi.container.servlet.ServletContainer </servlet-class> <servlet-name>jersey-serlvet</servlet-name>

20</servlet> 21 22<servlet-mapping> 23 24 <servlet-name>jersey-serlvet</servlet-name> <url-pattern>/rest/*</url-pattern>

25</servlet-mapping> 26<!-- .. -->

Enough configuration for now: Create a simple User object


User.java 1package ngdemo.domain; 2 3import javax.xml.bind.annotation.XmlRootElement; 4 5@XmlRootElement 6public class User { 7

8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26}

private String firstName; private String lastName;

public String getFirstName() { return firstName; }

public void setFirstName(String firstName) { this.firstName = firstName; }

public String getLastName() { return lastName; }

public void setLastName(String lastName) { this.lastName = lastName; }

and a service class


UserService.java 1package ngdemo.service; 2 3import ngdemo.domain.User; 4 5public class UserService { 6 7 8 9 10 11 12 13} } public User getDefaultUser() { User user = new User(); user.setFirstName("JonFromREST"); user.setLastName("DoeFromREST"); return user;

and finally the RESTful Service:


UserRestService.java

1package ngdemo.rest; 2 3import ngdemo.domain.User; 4import ngdemo.service.UserService; 5import ngdemo.service.UserServiceImpl; 6 7import javax.ws.rs.GET; 8import javax.ws.rs.Path; 9import javax.ws.rs.Produces; 10import javax.ws.rs.core.MediaType; 11 12 13@Path("/users") 14public class UserRestService { 15 16 17 18 19 20 21 22} } @GET @Produces(MediaType.APPLICATION_JSON) public User getDefaultUserInJSON() { UserService userService = new UserServiceImpl(); return userService.getDefaultUser();

Converting the User object to JSON via @Produces(MediaType.APPLICATION_JSON) requires jersey-json in web.xml ( POJOMappingFeature ).

Consuming web service from AngularJS (frontend)


Dont forget to add angular-resources.js to your index.html Consuming the web service:
services.js 1var services = angular.module('ngdemo.services', ['ngResource']);

2 3services.factory('UserFactory', function ($resource) { 4 5 6 7 8 9 10 }) } return $resource('/ngdemo/rest/users', {}, { query: { method: 'GET', params: {}, isArray: false

11});

Usage in controller:
controller.js 1var app = angular.module('ngdemo.controllers', []); 2 3app.controller('MyCtrl1', ['$scope', 'UserFactory', function ($scope, UserFactory) { 4 5 6 }) UserFactory.get({}, function (userFactory) { $scope.firstname = userFactory.firstName;

7}]);

Usage in view:
1<div> 2 3 4 <p> Result from RESTful service is: {{ firstname }} </p>

5</div>

Et voila:

Update (2013-07-18): You can clone a copy of this project here: https://github.com/draptik/angulardemorestful. To checkout the correct version for this demo, use the following code:
1git clone git@github.com:draptik/angulardemorestful.git 2cd angulardemorestful 3git checkout -f step1

In case you are not using git you can also download the project as ZIP or tar.gz file here: https://github.com/draptik/angulardemorestful/releases/tag/step1

RESTful CRUD With AngularJS


JUL 28TH, 2013

This post will show how to perform typical CRUD (create, read, update and delete) operations in AngularJS when consuming a RESTful web service. A prerequisite for this demo is a working RESTful web service. For a basic introduction on creating a Java based RESTful web service, see my introduction on how to consume a RESTful web service with AngularJS created by a Java backend. For completeness sake Ive added a Java based sample at the end of this post.

Frontend (AngularJS)
Views (Partials)
We will create three views. The first view will display all users ( user-list.html ):

The view also provides links to edit ( ng-click="editUser(user.id)" ) and delete ( ng-click="deleteUser(user.id)" ) specific users as well as a link to create a new user ( ng-click="createUser()" ).
1<div class="span6"> 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <table class="table table-striped table-condensed"> <thead> <tr> <th style="min-width: 80px;">First name</th> <th style="min-width: 80px;">Last name</th> <th style="width:20px;"> </th> <th style="width:20px;"> </th> </tr> </thead> <tbody> <tr ng-repeat="user in users"> <td>{{ user.firstName }}</td> <td>{{ user.lastName }}</td> <td><a ng-click="editUser(user.id)" class="btn btn-small btn-primary">edit</a></td> <td><a ng-click="deleteUser(user.id)" class="btn btn-small btn-danger">delete</a></td> </tr> </tbody>

19 20

</table> <a ng-click="createNewUser()" class="btn btn-small">create new user</a>

21</div>

The second and third view ( user-detail.html and user-creation.html ) both provide a form for entering the user properties.

They only differ in the actions provided. These actions ( cancel() , updateUser() , createNewUser() ) are invoked using ng-click :
user-[detail|creation].html 1<div class="container"> 2 3 <h1>User detail</h1>

4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27

<form novalidate="novalidate" class="form-horizontal"> <div class="control-group"> <label class="control-label" for="inputFirstName">First name:</label> <div class="controls"> <input type="text" id="inputFirstName" ng-model="user.firstName"/> </div> </div> <div class="control-group"> <label class="control-label" for="inputLastName">Last name:</label> <div class="controls"> <input type="text" id="inputLastName" ng-model="user.lastName"/> </div> </div> <div class="control-group"> <div class="controls"> <!-- user-detail.html: --> <a ng-click="cancel()" class="btn btn-small">cancel</a> <a ng-click="updateUser()" class="btn btn-small btn-primary">update user</a>

<!-- user-creation.html: --> <a ng-click="createNewUser()" class="btn btn-small btn-primary">create new user</a> </div> </div> </form>

28</div>

Controller
Next we will create three controllers corresponding to the three views. UserListCtrl
UserListCtrl
editUser

provides three functions editUser , deleteUser and createUser . merely redirect to a different partial view using service method
delete

and

createUser

AngularJss
deleteUser

$location function.

calls the

UserFactory

(which we will create

shortly). Furthermore the $scope.users is filled with the result from the UsersFactory.query() function.

Note that all required dependencies are injected into the controllers signature ( function ($scope, UsersFactory, UserFactory, $location) ).
controller.js 1var app = angular.module('ngdemo.controllers', []); 2 3app.controller('UserListCtrl', ['$scope', 'UsersFactory', 'UserFactory', '$location', 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 $scope.users = UsersFactory.query(); }]); }; // callback for ng-click 'createUser': $scope.createNewUser = function () { $location.path('/user-creation'); }; // callback for ng-click 'deleteUser': $scope.deleteUser = function (userId) { UserFactory.delete({ id: userId }); $scope.users = UsersFactory.query(); }; // callback for ng-click 'editUser': $scope.editUser = function (userId) { $location.path('/user-detail/' + userId); function ($scope, UsersFactory, UserFactory, $location) {

24 /* ... */

UserDetailCtrl and UserCreationCtrl


UserDetailCtrl

provides the function udateUser , which in turn invokes the

service method UserFactory.update . The $scope.user is filled with the result from calling UserFactory.show . cancel is just a convenient link redirecting back to the user-list view.
UserCreationCtrl

provides the function createNewUser ,

calling UsersFactory.create . Again, both controllers use $location to redirect back to the user-list partial view.

controller.js 1/* ... */ 2app.controller('UserDetailCtrl', ['$scope', '$routeParams', 'UserFactory', '$location', 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19app.controller('UserCreationCtrl', ['$scope', 'UsersFactory', '$location', 20 21 22 23 24 25 26 27 } }]); // callback for ng-click 'createNewUser': $scope.createNewUser = function () { UsersFactory.create($scope.user); $location.path('/user-list'); function ($scope, UsersFactory, $location) { $scope.user = UserFactory.show({id: $routeParams.id}); }]); }; // callback for ng-click 'cancel': $scope.cancel = function () { $location.path('/user-list'); }; // callback for ng-click 'updateUser': $scope.updateUser = function () { UserFactory.update($scope.user); $location.path('/user-list'); function ($scope, $routeParams, UserFactory, $location) {

Dont forget to map the views to the corresponding controllers in app.js using the $routeProvider :
app.js 1angular.module('ngdemo', ['ngdemo.filters', 'ngdemo.services', 'ngdemo.directives', 'ngdemo.controllers']). 2 3 4 config(['$routeProvider', function ($routeProvider) { $routeProvider.when('/user-list', {templateUrl: 'partials/user-list.html', controller: 'UserListCtrl'}); $routeProvider.when('/user-detail/:id', {templateUrl: 'partials/user-detail.html', controller:

5'UserDetailCtrl'}); 6 $routeProvider.when('/user-creation', {templateUrl: 'partials/user-creation.html', controller:

7'UserCreationCtrl'});

$routeProvider.otherwise({redirectTo: '/user-list'}); }]);

Service
AngularJS can consume the web service using $resource . This module is injected via 'ngResource' . We create two factories:
UsersFactory

(note the plural s) calls the web service with methods not requiring
create ).

an id ( query and
UserFactory

calls the web service with methods requiring a user id


delete ).

( show , update and


services.js

1var services = angular.module('ngdemo.services', ['ngResource']); 2 3services.factory('UsersFactory', function ($resource) { 4 5 6 7 }) return $resource('/ngdemo/web/users', {}, { query: { method: 'GET', isArray: true }, create: { method: 'POST' }

8}); 9 10services.factory('UserFactory', function ($resource) { 11 12 13 14 15 }) return $resource('/ngdemo/web/users/:id', {}, { show: { method: 'GET' }, update: { method: 'PUT', params: {id: '@id'} }, delete: { method: 'DELETE', params: {id: '@id'} }

16});

Backend (Java)
Here is an example of a RESTful web service created with Java:
UserRestService.java 1package ngdemo.web.rest; 2 3import com.google.inject.Inject;

4import ngdemo.domain.User; 5import ngdemo.service.contract.UserService; 6 7import javax.ws.rs.*; 8import javax.ws.rs.core.MediaType; 9import java.util.List; 10 11@Path("/users") 12public class UserRestService { 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 @PUT @Path("{id}") @Consumes(MediaType.APPLICATION_JSON) } @POST @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) public User create(User user) { return userService.createNewUser(user); } @GET @Path("{id}") @Produces(MediaType.APPLICATION_JSON) public User getUserById(@PathParam("id") int id) { return userService.getById(id); } @GET @Produces(MediaType.APPLICATION_JSON) public List<User> getAllUsersInJSON() { return userService.getAllUsers(); } @Inject public UserRestService(UserService userService) { this.userService = userService; private final UserService userService;

44 45 46 47 48 49 50 51 52 53 54 55}

@Produces(MediaType.APPLICATION_JSON) public User update(User user) { return userService.update(user); }

@DELETE @Path("{id}") @Produces(MediaType.APPLICATION_JSON) public void remove(@PathParam("id") int id) { userService.remove(id); }

You can clone a copy of this project here: https://github.com/draptik/angulardemorestful. To checkout the correct version for this demo, use the following code:
1git clone git@github.com:draptik/angulardemorestful.git 2cd angulardemorestful 3git checkout -f step4-angularjs-crud

In case you are not using git you can also download the project as ZIP or tar.gz file here: https://github.com/draptik/angulardemorestful/releases/tag/step4-angularjscrud
http://mobileappsresource.blogspot.in/2012/09/sample-application-with-angularjs.html

Sample Application with Angular.js


Sample Application with Angular.js: After I blogged a three-part Backbone.js tutorial (part 1, part 2, part 3), a number of people asked me to try Angular.js. So I decided to take it for a test drive. I thought it would be interesting to rebuild with Angular.js the Wine Cellar application I had built with Backbone.

If you are new to my Wine Cellar application, it is a simple CRUD app that allows you to manage (create, update, delete) wines in a Wine Cellar. The data is stored in a MySQL database that the client application accesses through a simple RESTful API. This seemed to be a good fit since CRUD applications are often positioned as the sweet spot for Angular.js. You can run the application here. The UI is intentionally plain to keep the focus on the key learning points. For obvious reasons, this online version is read-only. You can download the fully enabled version here.

Application Walkthrough
The best way to get started with Angular.js is to go through the excellent tutorial that is part of the documentation, so Ill only provide a high level overview of my code here. Like the Backbone.js implementation, the Angular.js version is a deep-linkable single page application. index.html is defined as follows: <!DOCTYPE HTML> <html xmlns:ng="http://angularjs.org"> <head> <title>Angular Cellar</title> <link rel="stylesheet" href="css/styles.css" /> </head> <body ng:controller="RouteCtrl">

<div id="header"> Angular Cellar <button ng:click="addWine()">New Wine</button> </div> <div id="sidebar"> <ng:include src="'tpl/wine-list.html'"></ng:include> </div> <div id="content"> <ng:view></ng:view> </div> <script src="lib/angular-0.9.19.min.js" ng:autobind></script> <script src="js/services.js"></script> <script src="js/controllers.js"></script> </body> </html> The application is driven by a set of Controllers that I defined in controllers.js as follows: function RouteCtrl($route) { var self = this; $route.when('/wines', {template:'tpl/welcome.html'}); $route.when('/wines/:wineId', {template:'tpl/wine-details.html', controller:WineDetailCtrl}); $route.otherwise({redirectTo:'/wines'}); $route.onChange(function () { self.params = $route.current.params; }); $route.parent(this); this.addWine = function () { window.location = "#/wines/add"; }; } function WineListCtrl(Wine) { this.wines = Wine.query(); }

function WineDetailCtrl(Wine) { this.wine = Wine.get({wineId:this.params.wineId}); this.saveWine = function () { if (this.wine.id > 0) this.wine.$update({wineId:this.wine.id}); else this.wine.$save(); window.location = "#/wines"; } this.deleteWine = function () { this.wine.$delete({wineId:this.wine.id}, function() { alert('Wine ' + wine.name + ' deleted') window.location = "#/wines"; }); } }

RouteCtrl defines the routes of the application. Each route is defined by a template that is rendered
in <ng:view> inside index.html. There can only be one <ng:view> in a document (more on that later). For example, here is the wine-list.html template: <ul ng:controller="WineListCtrl"> <li ng:repeat="wine in wines"> <a href='#/wines/{{ wine.id }}'>{{ wine.name }}</a> </li> </ul> The WineListCtrl and WineDetailCtrl controllers provide access to the data using a service defined in services.js as follows: angular.service('Wine', function ($resource) { return $resource('api/wines/:wineId', {}, { update: {method:'PUT'} }); }); Services provide a great way to abstract your data access logic, and to easily change it without impacting the rest of the application. For example, you could easily change the Wine service to use a Mock service instead of a RESTful service.

Impressions
I was able to build this application in a very limited amount of time with no prior knowledge of the framework. The data-binding implementation is nice, and, in general, the amount of boilerplate code you have to write is very limited. Frameworks are often a matter of style and personal preferences. Angular.js takes a more declarative approach than other frameworks. Based on this initial experience, I would also describe it as more prescriptive: I didnt have to spend a lot of time wondering what was the best way to do things as Angular.js tends to have clear utilization patterns. I havent spend enough time with the framework to determine if that comes at the cost of less control, and Id love to hear what other people are thinking. The only problem I ran into while building the application is the one route / one view coupling I

alluded to above. As suggested in this thread, you can use <ng:include> to bind partials in the page. The same thread also indicates that multiple <ng:views> per route definition will be supported in the future. I was able to handle the simple UI requirements of this app using one <ng:view> and one <ng:include>. For more complex applications, Id love the routing infrastructure to allow me to easily and arbitrarily add, remove, change, or animate different elements of the DOM when the route changes in order to support deeper UI transformations. Im sure there are ways to do this. If Angular.js folks are reading this post, Id love to hear what they think and whats coming.

Download
The application is available on GitHub here. You will need the RESTful services to run this application. A PHP version (using the Slim framework) is available as part of the download. If you want to test the application with a Java back-end, you can download the Backbone version here, and reuse its JAX-RS back-end.

Angularjs Tutorial: Testing using ngMock $httpBackend and karma. Node REST testing with Mocha
In Lesson 5, we implemented a node REST server to perform CRUD operations for device data. We have not yet hooked our server to mongodb, we will do that once we completely understand and unit test existing code base. This is all about Testing, Testing & more Testing. Client side testing using Karma & Server Side Node.js REST API testing using Mocha Our existing unit test cases handle static data being returned by the services. Since we have refactored our code to use $resource & $http, our unit test cases need to be refactored to utilize _$httpBackend_ which is a mock API provided by angularjs. Understanding $httpBackend takes a while and getting used to. The general steps in testing controllers using httpBackend are: 1. Inject _$httpBackend_ 2. Use expectGet, expectPOST & expectPUT & respond API to implement mock backend behavior 3. Run methods under test & verify results 4. _$httpBackend_.flush() to flush pending requests on demand

Testing Controllers Injecting _$httpBackend_ into the tests:


it('listDeviceController check for devices in the model', inject(function(_$httpBackend_, $rootScope, $controller, Devices) { var scope = $rootScope.$new(); var mockBackend = _$httpBackend_;

Implementing Mock Backend behavior:


mockBackend.expectGET('http://localhost:3000/devices'). respond([{id:0, name: "iphone", assetTag:"a23456", owner:"dev", desc:"iOS4.2"}]);

expectGET specifies the request expectation & respond implements the mock response

Run methods under test controllerSpec.js: var ctrl = $controller('deviceListController', {$scope: scope}, Devices);

This creates the deviceListController. In the controller the following statement "$scope.devices = Devices.query()" does a query using the Devices service. Essentially, it makes a http GET request. This is intercepted by the ngMock angularjs module & its response is provided to the controller.

Flush the response manually mockBackend.flush(); Test the conditions expect(scope.devices).toEqualData([{id:0, name: "iphone", assetTag:"a23456", owner:"dev", desc:"iOS4.2"}]);

Here is the code for controller CRUD testing with ngMock httpBackend: -'use strict'; /* jasmine specs for controllers go here */ /* Define all the services and controllers module, so they are accessable in your it's */ describe('controllers 1234567891011121314151617181920212223242526272829303132333 ', function(){

4353637383940414243444546474849505152535455565758596061626 3646566676869707172737475767778798081828384858687 beforeEach(function()


{ module('cotd.controll ers'); module('cotd.services '); module('ngResource');

this.addMatchers({ toEqualData: function(expected) {

return angular.equals(this.a ctual, expected); } }); });

it('listDeviceControl ler check for devices in the model', inject(function(_$htt pBackend_, $rootScope, $controller, Devices) { var scope = $rootScope.$new(); var mockBackend = _$httpBackend_;

mockBackend.expectGET ('http://localhost:30 00/devices'). respond([{id:0, name: "iphone", assetTag:"a23456", owner:"dev", desc:"iOS4.2"}]); var ctrl = $controller('deviceLi stController', {$scope: scope}, Devices);

//expect(scope.device s).toBeUndefined();

mockBackend.flush(); // check the number of devices expect(scope.devices. length).toEqual(1); expect(scope.devices) .toEqualData([{id:0, name: "iphone", assetTag:"a23456",

owner:"dev", desc:"iOS4.2"}]); }));

it('addDeviceControll er should return correct http response in the model after controller.add', inject(function(_$htt pBackend_, $rootScope, $controller, $location, Devices) { var scope = $rootScope.$new(); var mockBackend = _$httpBackend_;

mockBackend.expectPOS T('http://localhost:3 000/devices', {name: "iphone", assetTag:"a23456", owner:"dev", desc:"iOS4.2", id:1}). respond([{}]); var ctrl = $controller('addDevic eController', {$scope: scope}, $location, Devices); var item = {name: "iphone", assetTag:"a23456", owner:"dev", desc:"iOS4.2", id:1};

scope.add(item); // make sure the flag is true expect(scope.add).toB eTruthy(); // check actual add effected the devices list //expect(Devices.quer y().length).toEqual(8

); }));

it('editDeviceControl ler should successfully edit devices in the model', inject(function(_$htt pBackend_, $rootScope, $controller, $location, $routeParams, Devices) { var scope = $rootScope.$new(); var mockBackend = _$httpBackend_; var params = {}; params.id = 0;

mockBackend.expectGET ('http://localhost:30 00/devices/0', {"Accept":"applicatio n/json, text/plain, */*"}). respond({id:0, name: "iphone", assetTag:"a23456", owner:"qa", desc:"iOS4.3"});

var ctrl = $controller('editDevi ceController', {$scope: scope, $routeParams: params},$location, Devices); var item = {id:0, name: "iphoneupdate", assetTag:"a23456", owner:"qa", desc:"iOS4.3"};

mockBackend.flush();

// testing for update flag expect(scope.add).toB eFalsy(); expect(scope.device.d esc).toEqual("iOS4.3" );

mockBackend.expectPUT ('http://localhost:30 00/devices/0', {"id":0,"name":"iphon eupdate","assetTag":"a 23456","owner":"qa"," desc":"iOS4.3"}). respond({});

scope.update(item);

mockBackend.flush(); })); });


view rawcontrollerSpec.js hosted with by GitHub

--

Testing Services Testing services is fairly straightforward. We are mainly ensuring that the services send the right http requests to the backend & expect the right responses.

-'use strict'; /* jasmine specs for services go here */

123456789101112131415161718192021222324252627282930313 233343536373839404142434445464748495051525354555657585 describe('service', 96061626364656667 function() {

beforeEach(function(){

module('cotd.services'); module('ngResource'); });

describe('version', function() { it('should return current version', inject(function(version) { expect(version).toEqual(' 0.1'); })); }); describe('Devices', function() { it('should exist', inject(function(Devices){ expect(Devices).not.toBe( null); })); it('should contain devices', inject(function(_$httpBac kend_, Devices) { var mockBackend = _$httpBackend_;

mockBackend.expectGET("ht tp://localhost:3000/devic es"). respond([{id:0, name: "iphone", assetTag:"a23456", owner:"dev", desc:"iOS4.2"}]); var devices = Devices.query();

mockBackend.flush();

expect(devices.length).to Equal(1); })); it('should send a POST request', inject(function(_$httpBac kend_, Devices) { var item = {id:7, name: "iphone", assetTag:"a23456", owner:"dev",

desc:"iOS4.2"}; var mockBackend = _$httpBackend_; var newDevice = new Devices(item);

mockBackend.expectPOST("h ttp://localhost:3000/devi ces", {id:7, name: "iphone", assetTag:"a23456", owner:"dev", desc:"iOS4.2"}).respond({ }); newDevice.$save();

mockBackend.flush(); })); it('should send a PUT request', inject(function(_$httpBac kend_, Devices) { var mockBackend = _$httpBackend_;

mockBackend.expectPUT('ht tp://localhost:3000/devic es/0', {"id":0,"name":"iphoneupdate","assetTag":"a2345 6","owner":"dev","desc":" iOS4.3"}). respond({}); // modified device name test var item = {id:0, name: "iphone-update", assetTag:"a23456", owner:"dev", desc:"iOS4.3"}; Devices.update({deviceId: 0},item);

mockBackend.flush(); }));

}); });
view rawservicesSpec.js hosted with by GitHub

--

Trouble-shooting:

Error: Unknown provider: $resourceProvider <- devices="" div="" resource="">

ngResource is not part of angularjs core. So, you have to include it specifically in your test specs, like so:

describe('service', function() { beforeEach(function(){ module('cotd.services'); module('ngResource'); });

Testing the server - Node REST service testing using Mocha, Chai &supertest Now that we have extensively implemented client side unit testing specs, the focus naturally turns to testing the server side. After reviewing a bunch of server side testing frameworks, i think Mocha provides for a better suite since it allows for BDD a.k.a jasmine style syntax. This allows us to keep the testing constructs fairly consistent between client & server. Lets implement hands on mocha testing for our server.
We can accomplish Server side REST based testing easily by combining 3 frameworks Mocha, Chai & SuperTest. They play well nicely and makes it easier to write Node Based REST tests.

Step 1: is to add mocha, Chai & supertest to package.json { "name": "cotd-server", "description": "cotd backend", "version": "0.0.1", "private": "true", "dependencies": { "express": "3.2.2", "cors": "*"

}, "devDependencies":{ "mocha": "*", "chai": "*", "supertest": "*" }, "scripts":{ "test": "mocha" } }

Step 2: export the express app as a module in server.js. This is for Mocha to test the server functionality without running the server first. module.exports = app;

Step 3: create a test directory in your server folder and Create a new file for the test spec called test-devicesRest.js. Require mocha, chai & supertest in your test spec. var chai = require('chai'), express = require('express'), request = require('supertest'); var app = require('../server'); var expect = chai.expect; Step 4: writing a GET test describe('GET /devices', function(){ it('should return 200 and JSON with valid keys', function(done){ request(app) .get('/devices') .end(function(err, res){ //validate the keys in the response JSON matches, we dont care about the values expect(res.status).to.equal(200); expect(res.body[0]).to.have.keys(['id', 'name', 'assetTag', 'owner', 'desc']); done(); }); }); }); Step 5: creating a simple Makefile to run our test using Mocha. running make test on the command line should run mocha. It looks for the test directory and executes test specs within it. REPORTER = list #REPORTER = dot

test: @./node_modules/.bin/mocha \ --reporter $(REPORTER) test-w: @./node_modules/.bin/mocha \ --reporter $(REPORTER) \ --growl \ --watch

.PHONY: test Step 6: Write other tests. Here is a complete source code for our REST tests -var chai = require('chai'), express = require('express' ), request = require('supertes t'); var app = require('../serve r'); var expect = chai.expect;

12345678910111213141516171819202122232425262728293031323334353 /devices', 63738394041424344454647484950515253545556575859606162636465666 function(){ it('should 768697071727374

describe('GET

return 200 and JSON with valid keys', function(done){ request(app) .get('/devices') .end(function(err , res){ //validate the keys in the response JSON matches, we dont care about the values

expect(res.status ).to.equal(200); expect(res.body[0 ]).to.have.keys([ 'id', 'name', 'assetTag', 'owner', 'desc']); done(); }); }); }); describe('GET /devices/0', function(){ it('should return 200 and JSON with valid keys', function(done){ request(app) .get('/devices/0' ) .end(function(err , res){ //validate the keys in the response JSON matches, we dont care about the values expect(res.status ).to.equal(200); expect(res.body). to.have.keys(['id ', 'name', 'assetTag', 'owner', 'desc']); done(); }); }); }); describe('POST /devices', function(){

it('should return 200 and status JSON have valid status', function(done){ request(app) .post('/devices') .send({id:7, name: "iphone", assetTag:"a73856" , owner:"dev", desc:"iOS5"}) .end(function(err , res){ //validate the keys in the response JSON matches, we dont care about the values expect(res.status ).to.equal(200); expect(res.body). to.deep.equal({st atus: '1'}); done(); }); }); }); describe('PUT /devices/0', function(){ it('should return 200 and status JSON have valid status', function(done){ request(app) .put('/devices/0' ) .send({id:0, name: "iphone", assetTag:"a73856" , owner:"dev", desc:"iOS5"})

.end(function(err , res){ //validate the keys in the response JSON matches, we dont care about the values expect(res.status ).to.equal(200); expect(res.body). to.deep.equal({st atus: '1'}); done(); }); }); }); describe('Delete /devices/0', function(){ it('should return 200 and status JSON have valid status', function(done){ request(app) .del('/devices/0' ) .end(function(err , res){ //validate the keys in the response JSON matches, we dont care about the values expect(res.status ).to.equal(200); expect(res.body). to.deep.equal({st atus: '1'}); done(); }); }); });
view rawtest-devicesREST.js hosted with by GitHub

--

REST: CRUD with JAX-RS (Jersey)


In an earlier post I've discussed setting up Tomcat and Eclipse environment for JAX-RS. This post is an attempt to discuss some more basics of JAX-RS, specifically performing CRUD operations.

Prerequisites

Setup environment, discussed in this post Commons-HttpClient is used for the client program. Commons-codec and Commons-logging are its dependencies. All of them can be downloaded from Apache Commons website. Put those jars in the web application's lib.

Now some fun


If you are remotely interested in REST read Roy Fielding's dissertation on the topic. The chapter on RESTis a must read, not necessary to understand this exercise but strongly recommended to gain a big picture. As a part of the CRUD (creating, reading, updating and deleting) exercise let's try and create a Customer resource, retrieve Customer details, update the details and finally delete the Customer. To keep it simple and to keep the focus on the topic at hand I will not use a real database, instead use a file system leveraging Java's Properties mechanism. Our customer POJO has got 4 properties: id, first name, last name and a zip code. 01 02 private Integer customerId; public class Customer {

03 04

05 06

private String firstName;

07 08 09

private String lastName;

private String

zipcode; 10 //setters and getters }

11 12

Create
Let's start with CustomerResource class. A resource class is a Java class that uses JAX-RS annotations to implement corresponding Web resource. According to the specification, resource classes are POJOs that have at least one method annotated with @Path or a request method designator. 01 @Path ("customer") public class CustomerResource { public static final String DATA_FILE = "C:\\TEMP\\customerdata.txt";

02

03 04 05 06

@POST @Consumes ("application/xml") public Response addCustomer(InputStream customerData) { try { Customer customer = buildCustomer(null, customerData); long customerId = persist(customer, 0); return Response.created(URI.create("/" +

07 08

09

10 11

customerId)).build(); } catch (Exception e) { throw new WebApplicationException(e, Response.Status.INTERNAL_SERVER_ERROR); } }

12

13 14 15

Paths are relative. For an annotated class the base URI is the application context. For an annotated method the base URI is the effective URI of the contatining class. Base URIs are treated as if they ended in "/". So in the above example first line indicates how the Customer URI is mapped to/customer. addCustomer method is annotated as a method that responds to the HTTP POST method calls. As there is no @Path annotation on the method, the URI of the class is also the URI to access the method. Another important annotation is Consumes. It defines the media types that the methods of a resource class can accept. If not specified, it is assumed that any media type is acceptable. We don't have a Consumes annotation at the class level in this example, but if there is one the method level annotation takes precedence over the class level annotation. Response is returned to the client which contains a URI to the newly created resource. Return type Response results in an entity body mapped from the entity property of the Response with the status code specified by the status property of the response. WebApplicationException is a RuntimeException that is used to wrap the appropriate HTTP status codes. addCustomer method builds the customer from the received XML input and persists it. Code for the methods called in addMethod() is provided below and is selfexplanatory. These methods are used for both create and update purposes and hence the method signatures take Customer as a parameter. private long persist(Customer customer, long customerId) throws IOException 01 { Properties properties = new Properties(); properties.load(new FileInputStream(DATA_FILE));

02 03

04 if (customerId == 0) { customerId = System.currentTimeMillis(); }

05

06 07 08 09

properties.setProperty(String.valueOf(customerId), customer.getFirstName() + "," + customer.getLastName() + "," + customer.getZipcode()); properties.store(new FileOutputStream(DATA_FILE), null); return customerId; }

10

11 12 13 14 15

16

private Customer buildCustomer(Customer customer, InputStream customerData) throws ParserConfigurationException, SAXException, IOException { if (customer == null) { customer = new Customer(); }

17

18

19 20

21 22

DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); Document document = documentBuilder.parse(customerData); document.getDocumentElement().normalize();

23 24 25

26 27

NodeList nodeList = document.getElementsByTagName("customer");

28

Node customerRoot = nodeList.item(0); if (customerRoot.getNodeType() == Node.ELEMENT_NODE) { Element element = (Element) customerRoot; NodeList childNodes = element.getChildNodes(); for (int i = 0; i < childNodes.getLength(); i++) { Element childElement = (Element)childNodes.item(i); String tagName = childElement.getTagName(); String textContent = childElement.getTextContent();

29

30

31

32

33

34

35

36 37

if (tagName.equals("firstName")) { customer.setFirstName(textContent); } else if (tagName.equals("lastName")) { customer.setLastName(textContent); } else if (tagName.equals("zipcode")) { customer.setZipcode(textContent); } } } else { throw new WebApplicationException(Response.Status.INTERNAL_SE RVER_ERROR);

38 39

40 41 42 43 44 4 5 46 47 48 49

return customer; }

Test it
A test client method to test add operation looks something like the following, you may run this as a Java application via a main() method or it is easy to modify the following as a Junit test case. 01 private static void testAddCustomer() throws IOException, HttpException { final String addCustomerXML = "<customer>" +

02 03

04 05 06 07 08

"<firstname>Joe</firstname>" + "<lastname>Schmo</lastname>" + "<zipcode>98042</zipcode>" + "</customer>";

09 10

PostMethod postMethod = new PostMethod( "http://localhost:9000/RestExample/customer"); RequestEntity entity = new InputStreamRequestEntity( new ByteArrayInputStream(addCustomerXML.getBytes()), "application/xml"); postMethod.setRequestEntity(entity); HttpClient client = new HttpClient(); try { int result = client.executeMethod(postMethod); System.out.println("Response status code: " + result); System.out.println("Response headers:"); Header[] headers = postMethod.getResponseHeaders(); for (int i = 0; i < headers.length; i++) {

11 12 13 14

15 16

17

18

19

20

21

22 23 24 25 26

System.out.println(headers[i].toString()); } finally { postMethod.releaseConnection(); } }

Output
Response status code: 201 Response headers: Server: Apache-Coyote/1.1 Location: http://localhost:9000/RestExample/customer/1236708444823 Content-Length: 0 Date: Thu, 05 Mar 2009 12:15:22 GMT

Response status code 201 indicates the resource was created Location header displays the URI of the new resource that is created

Read
retrieveCustomer() method below illustrates the read operation: 01 02 03 @GET @Path ("{id}") @Produces ("application/xml") public StreamingOutput retrieveCustomer(@PathParam ("id") String customerId) { try { String customerDetails = loadCustomer(customerId); System.out.println("customerDetails: " + customerDetails); if (customerDetails == null) { throw new NotFoundException("<error>No

04 05

06

07

08 09

customer with id: " + customerId + "</error>"); }

10 11 12

13 14

final String[] details = customerDetails.split(",");

15

return new StreamingOutput() { public void write(OutputStream outputStream) { PrintWriter out = new PrintWriter(outputStream); out.println("< ?xml version=\"1.0\" encoding=\"UTF8\"?>"); out.println("<customer>"); out.println("<firstname>" + details[0] + "</firstname>"); out.println("<lastname>" + details[1] + "</lastname>"); out.println("<zipcode>" + details[2] + "</zipcode>"); out.println("</customer>"); out.close();

16

17

18 19

20

21

22 23 24

25 26

} }; } catch (IOException e) { throw new WebApplicationException(e, Response.Status.INTERNAL_SERVER_ERROR); } }

27 28 29 30 31

Get annotation indicates that this method is responsible for HTTP GET operations Path annotation indicates a dynamic id. As discussed above the paths are relative, so the URI /customer/{id} is the resultant path for this method Produces annotation, indicates the media type that is resulted from this operation PathParam annotation in the parameter reads the path id that is passed using the Path annotation StreamingOutput is returned by this resource method. StreamingOutput is a simpler version ofMessageBodyWriter. It has a write() method that has Output stream. All that you need is to write the data into that object, which will be returned to the client program.

Test it
In a web browser you may try the URI that was resulted from our create operation above (http://localhost:9000/RestExample/customer/1236708444823 for this example).

Output
You should see response something like the followiing: < ?xml version="1.0" encoding="UTF8" ?> <customer> <firstname>Joe</firstname> <lastname>Schmo</lastname> <zipcode>98042</zipcode>

2 3 4 5

</customer>

Update
POST is used create a new resource, PUT method updates the state of a known resource. You often see discussions about when to use POST vs PUT. My understanding is that if you are trying to create a brand new resource use POST, no Request-URI is required for POST. State is sent as a part of the BODY and the server should return you back HTTP code 201 (resource created), just like what we discussed in the CREATE section above. On the other hand, if you're updating the state of a resource use PUT. In this case you need the URI to the resource that you are trying to update. Update code follows: 01 02 03 @PUT @Path("{id}") @Consumes("application/xml") public void updateCustomer(@PathParam("id") String customerId, InputStream input) { try { String customerDetails = loadCustomer(customerId); if (customerDetails == null) { throw new WebApplicationException(Response.Status.NOT_FOUND); 10 } String[] details = customerDetails.split(","); Customer customer = new Customer(); customer.setFirstName(details[0]); customer.setLastName(details[1]);

04

05 06

07

08 09

11

12 13 14

15

customer.setZipcode(details[2]); buildCustomer(customer, input); persist(customer, Long.valueOf(customerId)); } catch (Exception e) { throw new WebApplicationException(e, Response.Status.INTERNAL_SERVER_ERROR); } }

16

17

18 19 20 21 22

PUT annotation marks the method as a resource method that handles HTTP PUT requests Path and Consumes annotations are already discussed in the earlier sections

Test it
Using HttpClient the update test can be performed as follows. In this example zip code of a customer is being updated: 01 private static void testUpdateCustomer() throws IOException, HttpException { final String addCustomerXML = "<customer>" + "<zipcode>98043</zipcode>" + "</customer>";

02 03 04 05 06

07 08

PutMethod putMethod = new PutMethod( "http://localhost:9000/RestExample/customer/1236708444823");

09 10 11 12

RequestEntity entity = new InputStreamRequestEntity( new ByteArrayInputStream(addCustomerXML.getBytes()), "application/xml"); putMethod.setRequestEntity(entity); HttpClient client = new HttpClient(); try { int result = client.executeMethod(putMethod); System.out.println("Response status code: " + result); System.out.println("Response headers:"); Header[] headers = putMethod.getResponseHeaders(); for (int i = 0; i < headers.length; i++) { System.out.println(headers[i].toString()); } } finally { putMethod.releaseConnection(); } }

13 14

15

16

17

18

19 20 21 22 23 24 25

Delete
The HTTP DELETE method requests the server to delete the resource identified by the request-URI.

01 02

@DELETE @Path("{id}") public void deleteCustomer(@PathParam("id") String customerId) { try { Properties properties = new Properties(); properties.load(new FileInputStream(DATA_FILE)); String customerDetails = properties.getProperty(customerId); if (customerDetails == null) { throw new WebApplicationException(Response.Status.NOT_FOUND);

03 04

05 06

07

08 09 10 11 1 2

} properties.remove(customerId); properties.store(new FileOutputStream(DATA_FILE), null);

13

} catch (Exception e) { throw new WebApplicationException(e, Response.Status.INTERNAL_SERVER_ERROR); } }

14 15 16

DELETE annotation is used to mark the method as a resource method that handles the resource-delete operation.

Test it
Test code for Delete. Attempting to delete the customer resource created earlier: 0 private static void testDeleteCustomer() throws HttpException

, IOException { DeleteMethod deleteMethod = new DeleteMethod( "http://localhost:9000/RestExample/customer/1236708444823"); HttpClient client = new HttpClient(); try { int result = client.executeMethod(deleteMethod); System.out.println("Response status code: " + result); System.out.println("Response headers:"); Header[] headers = deleteMethod.getResponseHeaders(); for (int i = 0; i < headers.length; i++) { System.out.println(headers[i].toString()); } } finally { deleteMethod.releaseConnection(); } }

02 03

04 05

06

07

08

09

10 11 12 13 14 15 16

output
Status code 204 is returned, stands for No Content. This code is used in cases where the request is successfully processed, but the response doesn't have a message body
Response status code: 204

Response headers: Server: Apache-Coyote/1.1 Date: Tue, 10 Mar 2009 18:34:46 GMT

Be Sociable, Share!
http://www.manning.com/mikowski/SPWA_meap_ch01.pdf One reason traditional websites are slow is because popular MVC server frameworks are focused on serving page after page of static content to an essentially dumb client. When we click a link in a traditional website slideshow, for example, the screen flashes white and everything reloads over several seconds: the navigation, ads, headlines, text, and footer are all rendered again. Yet the only thing that changes is the slideshow image and perhaps the description text. Worse, theres no indicator when some element of the page becomes functional. For example, sometimes a link can be clicked on as soon as it appears on a web page; other times we have to wait until the redrawing is 100% complete plus five seconds. This slow, inconsistent, and clunky experience is becoming unacceptable for an increasingly sophisticated web consumer. Product design is increasingly seen as the decisive factor in the success of commercial and enterprise web applications. SPAs are often the best choice to provide the optimal user experience. As a result, we expect the demand for user-focused design to drive SPA adoption and sophistication. SPA Definition An SPA is an application delivered to the browser that doesnt reload the page during use. Like all applications, its intended to help the user complete a task, such as write a document or administer a web server. We can think of an SPA as a fat client thats loaded from a web server.

You might also like