'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() {};