Skip to content

Instantly share code, notes, and snippets.

@kentcdodds
Created July 27, 2014 03:57
Show Gist options
  • Save kentcdodds/13aa10d7c3a8f8cc3fa7 to your computer and use it in GitHub Desktop.
Save kentcdodds/13aa10d7c3a8f8cc3fa7 to your computer and use it in GitHub Desktop.
StateUtilsProvider
// Companies config
angular.module('pk.web').config(function($stateProvider, StateUtilsProvider) {
'use strict';
var companyTemplateRoot = StateUtilsProvider.templates.home + 'Companies/';
$stateProvider.state('root.auth.home.companies', {
url: 'companies',
abstract: true,
template: StateUtilsProvider.absoluteDivView,
data: {
name: 'Companies'
}
});
$stateProvider.state('root.auth.home.companies.list', {
url: '',
templateUrl: companyTemplateRoot + 'CompaniesCtrl.html',
controller: 'CompaniesCtrl',
resolve: {
companies: StateUtilsProvider.findAll('company')
}
});
$stateProvider.state('root.auth.home.companies.new', {
url: '/new',
templateUrl: companyTemplateRoot + 'EditCompanyCtrl.html',
controller: 'EditCompanyCtrl',
resolve: {
isNew: StateUtilsProvider.resolveIdentity(true),
company: StateUtilsProvider.resolveNewResource('company')
}
});
$stateProvider.state('root.auth.home.companies.details', {
url: '/:id',
templateUrl: companyTemplateRoot + 'CompanyDetailsCtrl.html',
controller: 'CompanyDetailsCtrl',
resolve: {
company: StateUtilsProvider.resolveDSWithParam('company', 'id'),
admins: StateUtilsProvider.resolveAdmins('company', 'id'),
accesses: StateUtilsProvider.resolveAccesses('company', 'id'),
properties: StateUtilsProvider.resolveHttpGetWithParam('companies/:id/properties', 'id', 'property')
}
});
$stateProvider.state('root.auth.home.companies.edit', {
url: '/:id/edit',
templateUrl: companyTemplateRoot + 'EditCompanyCtrl.html',
controller: 'EditCompanyCtrl',
resolve: {
isNew: StateUtilsProvider.resolveIdentity(false),
company: StateUtilsProvider.resolveDSWithParam('company', 'id')
}
});
});
angular.module('pk.web.services').provider('StateUtils', function(_, FILE_ROOT, API_V1_URL) {
'use strict';
var rootUrl = '/';
var templateRoot = FILE_ROOT + 'components/pk.web/app/';
var divView = '<div ui-view></div>';
var absoluteDivView = '<div class="position-relative"><div ui-view class="animated-view"></div></div>';
var injector;
_.extend(this, {
rootUrl: rootUrl,
templates: {
root: templateRoot,
home: templateRoot + 'auth/home/',
anon: templateRoot + 'anon/'
},
templateRoot: templateRoot,
divView: divView,
absoluteDivView: absoluteDivView,
resolveHttpGet: resolveHttpGet,
resolveHttpGetWithParam: resolveHttpGetWithParam,
resolveParameter: resolveParameter,
resolveAuth: resolveAuth,
resolveDS: resolveDS,
findAll: findAll,
resolveDSWithParam: resolveDSWithParam,
resolveIdentity: resolveIdentity,
resolveNewResource: resolveNewResource,
resolveAdmins: resolveAdmins,
resolveAccesses: resolveAccesses,
resolveRandom: resolveRandom,
goBack: function goBackWrapper() {
getInjector().invoke(['$state', goBack]);
},
$get: function StateUtilsGet() {
return this;
}
});
function resolveHttpGet(url) {
return /*@ngInject*/ function httpGet($http, ChildResourceService) {
return $http.get(API_V1_URL + url).then(function(response) {
return ChildResourceService.findAndCreateChildResources(response.data);
});
};
}
function resolveHttpGetWithParam(url, param, type) {
return /*@ngInject*/ function httpGet($http, ChildResourceService, $stateParams, DS) {
return $http.get(API_V1_URL + url.replace(':' + (param || 'id'), $stateParams[param || 'id'])).then(function(response) {
if (type) {
if (_.isArray(response.data)) {
response.data = _.map(response.data, function(item) {
return DS.createInstance(type, item);
});
} else {
response.data = DS.createInstance(type, response.data);
}
}
return ChildResourceService.findAndCreateChildResources(response.data);
});
};
}
function resolveParameter(param) {
return /*@ngInject*/ function($stateParams) {
return $stateParams[param];
};
}
function resolveAuth() {
return /*@ngInject*/ function (LoginState) {
return LoginState.isAuthenticated();
};
}
function resolveDS(method, args) {
return /*@ngInject*/ function(DS) {
var instanceArgs = arrayify(args); // instanceArgs must exist because angular-data's doing something funky...
if (method === 'findAll' && instanceArgs.length === 1) {
instanceArgs.push({});
}
return DS[method].apply(DS, instanceArgs);
};
}
function findAll(what) {
return resolveDS('findAll', what);
}
function resolveDSWithParam(type, param) {
return /*@ngInject*/ function($stateParams, DS) {
var id = $stateParams[param || 'id'];
var item = DS.get(type, id);
if (item) {
return item;
} else {
return DS.find(type, id);
}
};
}
function resolveNewResource(type) {
return /*@ngInject*/ function newResource(DS) {
return DS.createInstance(type);
};
}
function resolveAdmins(type, idParam) {
return resolveAccessesOrAdmins('admins', type, idParam);
}
function resolveAccesses(type, idParam) {
return resolveAccessesOrAdmins('accesses', type, idParam);
}
function resolveAccessesOrAdmins(type, resourceType, idParam) {
return /*@ngInject*/ function accesses($http, $stateParams, DS, _) {
var resourceId = $stateParams[idParam || 'id'];
var endpoint = DS.definitions[resourceType].endpoint;
return $http.get(API_V1_URL + endpoint + '/' + resourceId + '/' + type).then(function(response) {
_.each(response.data, function(adminGroup, groupName) {
_.each(adminGroup, function(accessOrAdmin) {
accessOrAdmin.toUser = DS.createInstance('user', accessOrAdmin.toUser);
});
});
return response.data;
});
};
}
function resolveIdentity(val) {
return function() {
return val;
};
}
function resolveRandom(what) {
return /*@ngInject*/ function(DS, $q) {
if (_.isEmpty(DS.store[what].collection)) {
var deferred = $q.defer();
DS.findAll(what).then(function(whats) {
deferred.resolve(_.sample(whats));
}, deferred.reject);
return deferred;
} else {
return _.sample(DS.store[what].collection);
}
};
}
function goBack($state) {
$state.go($state.previousState, $state.previousParams);
}
function arrayify(obj) {
return angular.isArray(obj) ? obj : [obj];
}
function getInjector() {
if (!injector) {
injector = angular.element(document.getElementsByTagName('html')[0]).injector();
}
return injector;
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment