Previously I was calling an ASP.NET Web API controller from an AngularJS controller using the $http service.
$http.get(serviceUrl).success(function (data) {
$scope.videos = data;
});
With a little bit of work I can use a higher level of abstraction in Angular – a custom service based on $resource. $resource is a factory that can create an object with methods that map to the WebAPI action methods I need to invoke. If I scaffold a VideoController for the WebAPI, the default actions will let me:
- GET all videos
- GET a video by ID.
- POST a new video
- PUT an updated video
- DELETE a video
To configure a service that will map JavaScript methods to these controller actions on the server, I'll need to use the .module API.
angular.module("videoService", ["ngResource"]).
factory("Video", function ($resource) {
return $resource(
"/api/videos/:Id",
{Id: "@Id" },
{ "update": {method:"PUT"} }
);
});
These lines of code are registering a videoService that depends on ngResource (another module in Angular). When a controller requires a video service, the factory method will take care of configuring the service using $resource. There are a few interesting lines of code here.
- "/api/videos/:Id" is the URL to interact with the resource on the server (you could send this value to the client instead of hard coding the value). The :id part tells Angular how part of the URL path is parameterized with data.
- {Id: "@Id"} tells Angular to grab the ID parameter for the URL from an object's Id property.
- { "update": {method:"PUT"}} tells Angular to add a custom method to the resource. The custom method has the name "update" and it will use HTTP PUT when sending a message to the server. The default methods for a resource include query, save, and delete, which map to GET, POST, and DELETE verbs, so we needed one more for PUT.
Another call to .module will tell Angular that my app requires the videoService as a dependency.
angular.module("videoApp", ["videoService"]);
And now the controller can "ask" for Angular to inject a video service by adding another parameter named "Video" to the constructor (Video was the first parameter to .factory, above):
var VideoController = function ($scope, Video) {
/// ...
}
What used to require three lines of code to grab all videos from the server now requires a single line of code*.
$scope.videos = Video.query();
The resource service returns an empty array in this scenario, but there is a promise working behind the scenes to populate the array with data (which data binding will then automatically push into the view). The delete, save, and update methods are also available on these objects once they return from the server.
$scope.createVideo = function (newVideo) {
newVideo.$save();
$scope.videos.push(newVideo);
};
$scope.updateVideo = function(video) {
video.$update();
};
$scope.deleteVideo = function (video) {
video.$delete();
$scope.videos = _.without($scope.videos, video);
};
The code is naïve and assumes a call to the server will always work. There are a couple strategies for error handling, including passing an error handler to the resource methods, or registering an $http interceptor to process HTTP messages at a global level (that's foreshadowing). For now, the heart of the code is in an updated gist.
* Still not entirely comfortable with the naming conventions I want to use for this scenario.
If you update or restore your NuGet packages in an ASP.NET MVC 4 application, you've probably discovered the breaking changes in jQuery 1.9.x.
From the upgrade guide:
jQuery 1.9 removes or modifies several APIs that behaved inconsistently or inefficiently in the past. The majority of these changes have been foreshadowed by their deprecation in previous versions of jQuery, particularly 1.7 and 1.8.
Depending on what other packages you've upgraded or installed (like jQuery UI, jQuery Mobile), you'll see various runtime errors in a JavaScript debugger. Here is the error thrown by the jquery.unobtrusive-ajax.js file authored by Microsoft to form a bridge between HTML helpers and JavaScript code.

Update: If the only script problems you are seeing are in the jQuery.unobtrusive scripts, make sure to use the NuGet update tab to update all your unobtrusive script packages from Microsoft. Unfortunately, many packages with a dependency on jQuery say they require jQuery 1.4.4 to jQuery 2.0, so with the breaking changes in 1.9 you’ll need to manually update packages.
There are many other possible solutions if you can't change your own code right away, but here are two easy ones.
1) install-package jQuery.Migrate.
jQuery Migrate is a script you'll want to include in pages immediately after jQuery. The migration script will add back some of the features removed from jQuery 1.9 (like the live function). The development version also provides trace messages that will highlight the deprecated APIs in use so you can update your own code to the newer APIs.

2) install-package jQuery –Version 1.8.3
You can always revert to a previous version of jQuery if you don't want to use the additional migration script.
Hope that helps!
Since I started a series of posts on AngularJS, I've had a few people ask me why I like the framework.
One year ago I wrote a post with the title "Plain Old JavaScript". This post originated after working with various frameworks and deciding that two-way data binding was not a feature I was willing to achieve by sacrificing JavaScript objects on the Altar Of Observability.
Specifically, the func-ifying of object properties to raise change notifications corrupts my models with infrastructure. The functions make the code harder to change, harder to work on as a team, and harder to debug. These are my personal feelings based on my own observations, and I'm not saying the approach is wrong or doesn't work.
You can like caramel, but I prefer chocolate.
We can both eat ice cream with a dessert topping.
One of the reasons I kept coming back to Angular was because it offers two-way data binding without funcing up the model. At first I couldn't believe the change detection could possibly work, but it does work well by using some smarts. There are watchers, listeners, and a snapshot strategy that will look for changes after your code executes and manipulates the model. The change detection feature includes my favorite comment of the entire Angular code base (in the $digest method):
// Insanity Warning: scope depth-first traversal // yes, this code is a bit crazy, but it works and we have tests to prove it!
So, it does work, and there are tests to prove it.
Angular is broken down into components like controllers, views, models, and services. These names are familiar to anyone who has worked on projects using separated presentation patterns. There are also directives, filters, modules, and other abstractions that seem to achieve the right balance of complexity versus separation of concerns.
Model View Controller and Dependency Injection are the two patterns that jump out at the start, but there are other comfortable, familiar patterns in Angular, including it's approach to view composition and dependency management.
Angular help you write test friendly code. Even the tutorial demonstrates unit tests and end-to-end tests using Jasmine's BDD syntax.
Not every framework is perfect, and you'll find scenarios where Angular is not a good fit. There are certainly scenarios when change detection will be milliseconds slower than observing changes. It's not obvious how to track animations or respond to focus events. Form validation is subpar. Angular is not minimalistic and comes with strong opinions. Writing lower level components, like custom directives, requires some focused effort. You also need some understanding of prototypal inheritance to avoid getting into trouble in more advanced scenarios.
I like Angular because I have fun writing code on top of the framework, and the framework doesn't get in the way. Models are just models, and views have sexy {{data.binding}} expressions. I do have an affinity for { and }.
I also believe AngularJS is the framework in the best position to take advantage of future improvements in the JavaScript language and the DOM APIs.
That's why I like AngularJS, but frameworks are a personal choice.
The last feature I need to add for the video sample is the ability to edit and delete videos. One approach with Angular is to bind edit and delete button click events to the model using the ng-click click directive, which we've seen before.
<tr ng-repeat="video in videos">
<td>{{video.Title}}</td>
<td>{{video.Length}}</td>
<td>
<button ng-click="editVideo(video.Id)">Edit</button>
<button ng-click="deleteVideo(video.Id)">Delete</button>
</td>
</tr>
What's new in the two usages of ng-click here is the complexity of the expression inside. More on expressions later, but ultimately the expression will invoke delete and edit methods with parameters, where the delete method can look like the following:
$scope.deleteVideo = function (id) {
$http.delete(serviceUrl + "/" + id)
.success(function () {
$scope.videos = _.reject($scope.videos, videoFinder(id));
});
};
This code is using Underscore's reject to help update the model.
All the HTML and JavaScript for the sample is in a gist, and if you followed (closely) the original course at Pluralsight, you might remember the original sample was around 120 lines of script with jQuery and Handlebars. The same features in Angular require around 60 lines of script. However, we've only scratched the surface of what we can do with AnjularJS. Not only can we write less code, we can add some new features using additional Angular APIs, and still have a testable controller.
We'll look at some of these additional features in the future. For now I wanted to return to the ng-click expressions.
At first glance, ng-click looks similar to writing JavaScript code inside an onclick attribute, which we've learned to avoid for many good reasons. However, the resemblance is only superficial. An ng-click directive doesn't prevent progressive enhancement or go against the true spirit of unobtrusive JavaScript. I think of ng directives and other {{expressions}} as natural extensions to the declarative language of HTML. Angular uses a compiler service at runtime to process the directives and construct linkages between the HTML view and a model.
Another significant difference between ng-click and onclick is the execution context. Code inside an onclick attribute executes against the global window object, while an expression inside of ng-click executes against a specific scope object, typically the scope object representing the model for the current controller.
In other words, if you wanted to invoke the global alert function in JavaScript, the following onclick handler will work:
<button onclick="alert('hello!')">Say Hi</button>
However, the following ng-click code will not invoke the global alert function:
<button ng-click="alert('hello!')">Say Hi</button>
The only way for the code inside the directive above to work is to have an alert method defined for the current scope.
$scope.alert = function(message) {
$window.alert(message);
};
In this example we'll forward the call to the global alert function by using a well known $window service that is injected into the controller (which is a testable approach to using the window object).
The code in the ng-click attribute for the edit and delete buttons actually executes against a scope defined by the ng-repeat directive. The ng-repeat directive is providing a video for every object in the videos collection, and the repeat scope prototypically inherits from the controller scope (which is why both deleteVideo from the controller scope and video.Id from the repeat scope are available to use in the expression). For more details on how scopes in Angular work, see "The Nuances of Scope Prototypal Inheritance". Scopes are important to understand.
One final difference between ng-click and onclick is that the expression syntax supported by ng-click is like a subset of JavaScript. You can make method calls, use a ! operator, and even perform an assignment (which is frowned upon), but you cannot use flow control statements, among other things. Remember the view is supposed to be simple, so expressions typically reference a property or invoke a method to keep most of the logic inside a controller.
Continuing to reach for feature parity with my original jQuery with ASP.NET Web API sample, I need to have the ability to create a new video.
The original sample caught the form submit event and serialized form data for an AJAX submission to the web server.
With AngularJS I only need to bind some form elements to the model (using the ng-model directive), and bind a click event (with the ng-click directive).
<form>
<input type="hidden" ng-model="editableVideo.Id"/>
<label>Title:</label>
<input type="text" ng-model="editableVideo.Title" required />
<label>Length</label>
<input type="number" ng-model="editableVideo.Length" min="1" max="360" />
<input type="submit" value="Save" ng-click="saveVideo()" />
</form>
Note there is also an ngSubmit directive, but Angular will prevent the default form submission if I have only one or the other. When the user clicks save, I just need to post the new video information to the Web API. The controller code now looks like the following:
var VideoController = function ($scope, $http) {
var serviceUrl = "/api/videos";
var blankVideo = {
Id: "",
Title: "",
Length: 75
};
var refreshVideos = function() {
$http.get(serviceUrl).success(function (data) {
$scope.videos = data;
});
};
$scope.isEditVisible = false;
$scope.showEdit = function () {
$scope.isEditVisible = true;
$scope.editableVideo = angular.copy(blankVideo);
};
$scope.saveVideo = function() {
$scope.isEditVisible = false;
$http.post(serviceUrl, $scope.editableVideo)
.success(function (video) {
$scope.videos.push(video);
});
};
refreshVideos();
};
Notice it is easy to keep private methods and data inside a controller.
Next I need the ability to delete and edit existing videos, and then the sample will behave exactly like the original "jQuery only" sample. We'll look at those scenarios next.
One of the nicer features of Angular is the framework's ability to separate the roles of the model, the view, and the controller. The separation is clean enough that you shouldn't need to manipulate the DOM directly from code inside the controller. Instead, the controller only manipulates the model, which influences the view through data bindings and directives. The end result is a clean and testable.
In the last post we saw how to build a simple tabular display with Angular and the Web API, but in my original non-Angular sample I also had a "Create Video" button that would open a form with inputs for the user to enter new video information. This was all achieved using jQuery to wire up click event handlers and using jQuery to find DOM elements by ID, then using jQuery to toggle visibility. With AngularJS none of the jQuery code is needed.
Let's add the following HTML inside the ng-app div from the previous post:
<button ng-click="showEdit">Create Video</button>
<div ng-show="isEditVisible">
<hr />
<form>
<input type="hidden" name="id" value =""/>
<label for="title">Title:</label>
<input type="text" name="Title" value="" />
<!-- more inputs... -->
</form>
</div>
Pay no attention to what is inside the form just yet. The focus of this post is the ng-click and ng-show directives. Directives in Angular are programmable components that can perform specific tasks to make the application more declarative and easy to maintain and test.
The ng-click directive, as you might suspect, is a directive containing an expression for Angular to evaluate against the current controller scope when the user clicks the button. The ng-show directive contains an expression that will determine the visibility of an element. If isEditVisible is truthy the element will be visible, if falsy the element will dissapear. There is also an ng-class directive to set CSS classes on an element, so these directives help you stay "hands off" the DOM from a controller. There are additional directives available, and you can always plug in custom directives.
With the HTML in place, we only need a few lines of code in the controller to hide the form on load, and show the form when a user clicks the button.
var VideoController = function ($scope, $http) {
$scope.isEditVisible = false;
$scope.showEdit = function () {
$scope.isEditVisible = true;
};
$http.get('/api/videos/').success(function (data) {
$scope.videos = data;
});
};
Fans of XAML and the MVVM pattern might see some similarities in how Angular's MVC approach works. One significant difference to me is the clean markup compared to XAML. I always felt bad when I saw the ceremony of {Bindingicus Pathius=isEditVisible , Converteralicus={StaticusResourcious visibilityFromBool}} in XAML.
In my MVC 4 Fundamentals video I have a section using the ASP.NET Web API on the server with jQuery and Handlebars on the client to build a somewhat interactive UI. A few people have asked what the code would look like with AngularJS.
The first part of the example, display a list of videos, is easy with Angular. Here is the HTML:
<div ng-app ng-controller="VideoController">
<table>
<thead>
<th>Title</th>
<th>Length</th>
<th></th>
</thead>
<tbody>
<tr data-id="{{video.Id}}" ng-repeat="video in videos">
<td>{{video.Title}}</td>
<td>{{video.Length}}</td>
<td>
<button class="editVideo">Edit</button>
<button class="deleteVideo">Delete</button>
</td>
</tr>
</tbody>
</table>
</div>
The ng-app directive represents the application "root" for angular. Most applications would have ng-app on the body element, or the top html element, but you can also root the application further into the DOM. The ng-controller directive provides the name of a controller function for Angular to find and invoke. The controller provides the model and allows us to use data binding in between the model and the view (the HTML).
The controller function looks like this:
var VideoController = function($scope,$http) {
$http.get('/api/videos/').success(function(data) {
$scope.videos = data;
});
};
Angular will inject the $scope and $http parameters into the controller (names are significant). $scope is where we can place the model, while $http is a service that provides low-level HTTP communication (we'll see a higher level service in a later post). The above code is calling a Web API controller on the server to retrieve a list of videos, and placing them into the $scope when the call is successful. Back in the HTML, an ng-repeater will loop through the videos when they become available (Angular knows when the model changes), and outputs table rows with video information (via {{ }} templates).
The above is a quick demonstration of why I like Angular. It's quick, clean, and easy to learn. In my original demo I also inserted, deleted, and edited videos. We'll take a look at these scenarios next.