Ben Nadel
On User Experience (UX) Design, JavaScript, ColdFusion, Node.js, Life, and Love.
I am the chief technical officer at InVision App, Inc - a prototyping and collaboration platform for designers, built by designers. I also rock out in JavaScript and ColdFusion 24x7.
Meanwhile on Twitter
Loading latest tweet...
Ben Nadel at Scotch On The Rock (SOTR) 2010 (London) with:

httpi - A Lightweight $resource-Inspired Module For AngularJS

By Ben Nadel on

As I blogged about before, I'm not a huge fan of the $resource module in AngularJS. But, it does have some features that I do like; namely, URL interpolation and the encapsulation of URLs across requests to the same resource. I created the "httpi" module in an attempt to build these features on top of the $http service while still providing direct access to the flexibility of the $http service underneath.


 
 
 

 
  
 
 
 

View the httpi project on my GitHub account.

The httpi service is really just a preprocessor for the underlying $http service. It takes your configuration object, interpolates the URL (hence the "i" in "httpi"), and then passes the updated configuration object off to $http. It then returns the same promise that the $http service returned to it.

The httpi service can also create $resource-inspired objects that apply the same URL across different HTTP calls. But, like the httpi service, each HttpiResource instance method takes a normal configuration object, modifies it, and then passes it off to the underlying $http service.

NOTE: When I say "$resource-inspired," I do so very loosely. I do not mean to imply that I am recreating the $resource feature-set; rather, that I am extracting what I personally found useful in the $resource-oriented approach.

To see this in action, take a look at the code below (which is the example on my GitHub project page). I'm creating an httpi resource and then invoking several of the convenience methods:

  • <!doctype html>
  • <html ng-app="Demo">
  • <head>
  • <meta charset="utf-8" />
  •  
  • <title>
  • Using The httpi Service To Make AJAX Requests In AngularJS
  • </title>
  •  
  • </head>
  • <body ng-controller="DemoController">
  •  
  • <h1>
  • Using The httpi Service To Make AJAX Requests In AngularJS
  • </h1>
  •  
  •  
  • <!-- Initialize scripts. -->
  • <script type="text/javascript" src="vendor/angular-1.2.16.min.js"></script>
  • <script type="text/javascript" src="../lib/httpi.js"></script>
  • <script type="text/javascript">
  •  
  • // Define the module for our AngularJS application.
  • var app = angular.module( "Demo", [ "httpi" ] );
  •  
  •  
  • // -------------------------------------------------- //
  • // -------------------------------------------------- //
  •  
  •  
  • // I control the main demo.
  • app.controller(
  • "DemoController",
  • function( $scope, httpi ) {
  •  
  • console.warn( "None of the API endpoints exist - they will all throw 404." );
  •  
  • // NOTE: The (.|.) notation will be stripped out automatically; it's only
  • // here to improve readability of the "happy paths" for interpolation
  • // labels. The following urls are pre-processed to be identical:
  • // --
  • // api/friends/( :listCommand | :id/:itemCommand )
  • // api/friends/:listCommand:id/:itemCommand
  • var resource = httpi.resource( "api/friends/( :listCommand | :id/:itemCommand )" );
  •  
  • // Clear list of friends - matching listCommand.
  • resource.post({
  • data: {
  • listCommand: "reset"
  • }
  • });
  •  
  • // Create a new friend - no matching URL parameters.
  • resource.post({
  • data: {
  • name: "Tricia"
  • }
  • });
  •  
  • // Get a given friend - ID matching.
  • resource.get({
  • data: {
  • id: 4
  • }
  • });
  •  
  • // Make best friend - ID, itemCommand matching.
  • resource.post({
  • data: {
  • id: 4,
  • itemCommand: "make-best-friend"
  • }
  • });
  •  
  • // Get gets friends - no matching URL parameters.
  • resource.get({
  • params: {
  • limit: "besties"
  • }
  • });
  •  
  • // Get a friend as a JSONP request.
  • // --
  • // NOTE: The "resource" will auto-inject the "JSON_CALLBACK" marker that
  • // AngularJS will automatically replace with an internal callback name.
  • resource.jsonp({
  • data: {
  • id: 43
  • }
  • });
  •  
  • }
  • );
  •  
  • </script>
  •  
  • </body>
  • </html>

Notice that the configuration objects passed into the "resource" methods don't have to include the Method or URL properties - these are automatically interpolated and injected into the configuration object before they are passed-off to the underlying $http service.

When we run the above code, we get the following network activity:

POST /api/friends/reset
POST /api/friends
GET /api/friends/4
POST /api/friends/4/make-best-friend
GET /api/friends?limit=besties
GET /api/friends/43?callback=angular.callbacks._0

Of course, you don't have to use the resource part of the module; the resource is kind of like a preprocessor for the httpi service which is, itself, a preprocessor for the $http service. If you call the httpi service directly, you'll still get the URL interpolation - you simply have to pass-in the URL with each request.

Obviously, the value of this module is heavily colored by my own experience with the $resource module in AngularJS. If you're loving $resource, I am not suggesting that you stop using it. But, for me personally, it wasn't a huge value-add. So, I tried to take the parts that I did like and rebuild them on top of the $http service in a very transparent way.




Reader Comments

Post A Comment

You — Get Out Of My Dreams, Get Into My Comments
Live in the Now
Oops!
Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.