AngularJS $resource is a great tool for quickly connecting to RESTful services. Unfortunately the docs and examples quickly lead you to bad design.
This presentation is a short set of design patterns for using the $resource service. It focuses on how to use promises and callbacks in your application for error handling, API isolation and extensibility.
I skip the details on the $resource syntax. The AngularJS docs do a great job there.
2. ABOUT @SACHINKAGRAWAL
I run EDP Software and we build a product called SchedulePro
Relatively new to AngularJS. Just now starting to use it in
Production scenarios
Background
8 years as a Program Manager at Microsoft before EDP Software
University of Waterloo alumni
We’re hiring! http://www.edpsoftware.com/about-edp-software/careers/
Email: hr@edpsoftware.com
3. GOALS FOR TODAY
Use $resource for connecting to REST web services
Discuss how to use $resource in a web application
Separate API details from application
Where to put common tasks like data transforms
Get feedback from the group on what else could be done better!
4. MY THOUGHTS ON COMMON EXAMPLES
Most documentation is too simple
Logic for using $http or $resource is built right into a controller
Two big issues that I found
REST API changes are not isolated
No common place to handle async status
5. $RESOURCE INTRO
Provides a really simple way to grab data from a REST endpoint
Standard methods for query, get, save, delete
Easy to define urls, parameters, custom additions, etc. (see docs)
Super simple to get started (you should turn this into a factory)
var ResourceObject = $resource("http://foo/Object/…");
var resultData = ResourceObject.query();
//The following call will be bound to the scope and then UI if rendered
//UI will magically update when the request is complete
$scope.foo = ResourceObject.query();
6. ASYNCHRONOUS CALLS AND PROMISES
Angular uses promises heavily in many of the built in APIs
$q is a lightweight promise implementation
Promises provide the ability to control and chain requests together.
NOTE: The results of $resource (or $http) are asynchronous. If your
code expects data immediately after calling a query, you will have an
empty result!!!
NOTE 2: Angular calls the digest loop after $http calls complete
which is why the UI seems to magically get the data
7. $HTTP VS. $RESOURCE
PROMISES VS. CALLBACKS
$http uses promises as the design pattern for managing async
actions
$resource defaults to using a callback structure
Allow you to access the promise exposed by $http
HELP Me Vangular!?
Suggestions on which route to choose? I exposed the promise from
$resource in my last example.
8. CALLBACKS FOR SETTING RESULTS
BAD – What many base examples show
No way of taking action when the async call completes.
Easy to start with but quickly limits your application
Good – Use the callback function to set variables on the scope
$scope.foo = ResourceObject.query();
ResourceObject.query(function(results){
$scope.foo = results;
//Do any other actions here….
});
10. CREATING A LAYER OF ABSTRACTION
Isolate - REST APIs may be out of your control (e.g. 3rd party).
Create a factory with your own API
Simplify/Transform data
Promises can be chained together
The return result from one promise goes into the next as the incoming
data
11. EXAMPLE
angular.module('sampleApp').factory('resourceAPI', ['$resource', function ($resource) {
var ResourceObject = $resource("http://foo/Object/…");
return {
getTransformedValues: function () {
return ResourceObject.query().$promise.then(function(data) {
//Make whatever transforms are required
//Underscore library is useful here
data = ....
//The returned data will be the result
//when the promise resolves
return data;
});
}, otherFunctionsInAPI: function() {}
};
} ]);
12. EXAMPLE PART II
Meanwhile.... In your controller
$scope.showSpinner = true;
resourceAPI.getTransformedValues().then(function(data){
$scope.foo = data;
return data;
}, function(error){
//Perform whatever error handling you wish
})[‘finally’](function(){
//Odd finally syntax is for IE8 compat
$scope.showSpinner = false;
});