Skip to content

Instantly share code, notes, and snippets.

@bclinkinbeard
Created August 21, 2012 01:35
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save bclinkinbeard/3410406 to your computer and use it in GitHub Desktop.
Save bclinkinbeard/3410406 to your computer and use it in GitHub Desktop.
AngularJS Response Interceptor Demo

This is a simple demo of how to create and use a Response Interceptor in AngularJS. In this case we are using the interceptor to convert the objects created from a JSON data load into typed instances of a custom "class".

'use strict';
var app = angular.module( 'app', [] );
// register the interceptor during module config
app.config( function( $httpProvider ) {
$httpProvider.responseInterceptors.push( interceptor );
} );
// initiate data load on module start up
app.run( function( $http, $rootScope ) {
$http.get( 'data.json', { cls: District, initFn: createSchools } )
.success( function( data, status, headers, config ) {
var district = data[ 0 ];
$rootScope.msg1 = "var district = data[ 0 ];";
var listContainsDistricts = new String( district instanceof District );
$rootScope.msg2 = "district instanceof District = " + listContainsDistricts;
var districtHasSchools = new String( district.schools[ 0 ] instanceof School );
$rootScope.msg3 = "district.schools[ 0 ] instanceof School = " + districtHasSchools;
} );
} );
var interceptor = function( $q ) {
return function( promise ) {
// convert the returned data using values passed to $http.get()'s config param
var resolve = function( value ) {
convertList( value.data, value.config.cls, value.config.initFn );
};
var reject = function( reason ) {
console.log( "rejected because: ", reason );
};
// attach our actions
promise.then( resolve, reject );
// return the original promise
return promise;
}
};
// using angular's forEach method, pass each item in a list to convertInstance
var convertList = function( list, type, initFn ) {
list = angular.forEach( list, function( o, index ) {
this[ index ] = convertInstance( o, type, initFn );
}, list );
};
// using angular's extend method, replace each object with a typed instance
// optionally call an initialization function for each new instance
var convertInstance = function( instance, type, initFn ) {
instance = angular.extend( new type(), instance );
if( initFn )
initFn.call( instance );
return instance;
};
// convert each District's list of Schools
var createSchools = function() {
convertList( this.schools, School );
};
// dummy types. these would normally be real "classes".
var District = function() {};
var School = function() {};
[{"id":"d1","name":"District 1","schools":[{"id":"s0","school":"School 0"},{"id":"s1","school":"School 1"},{"id":"s2","school":"School 2"},{"id":"s3","school":"School 3"},{"id":"s4","school":"School 4"}]},{"id":"d2","name":"District 2","schools":[{"id":"s5","school":"School 5"},{"id":"s6","school":"School 6"},{"id":"s7","school":"School 7"},{"id":"s8","school":"School 8"},{"id":"s9","school":"School 9"}]}]
<!DOCTYPE html>
<html lang="en" ng-app="app">
<head>
<meta charset="utf-8">
<title>AngularJS Response Interceptor Demo</title>
</head>
<body>
{{msg1}}
<br/>
{{msg2}}
<br/>
{{msg3}}
<script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.1/angular.min.js"></script>
<script src="app.js"></script>
</body>
</html>
@ThomasBurleson
Copy link

@ben,

  1. I recommend that your $http data service be registered as a named, service instance with AngJS; instead of generic app.run function.
  2. Note that you can return promise.then( resolve, reject ); since then( ... ) actually itself returns a new promise wrapper.
  3. I think your solution here submits an interceptor to be used with any $http reponse; which is often NOT what is wanted.

You may want to look at Twitter Search $twitter service and how it uses $http with promises and data transforms.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment