Skip to content

Instantly share code, notes, and snippets.

@jwcarroll
Created February 26, 2016 19:13
Show Gist options
  • Save jwcarroll/aa0e2026591cf2f9b3f9 to your computer and use it in GitHub Desktop.
Save jwcarroll/aa0e2026591cf2f9b3f9 to your computer and use it in GitHub Desktop.
Monkey patching angular-ui state provider
import * as ng from 'angular';
import {stateProviderDecorator} from './state-provider-decorator';
//In our module we load up the
ng.module('my-app', [])
.config(stateProviderDecorator)
.config(function($stateProvider){
//Configure states normally
$stateProvider.state('main',{
//don't decorate this state
someOptOutProperty:true,
url: '/',
template: '<h1>Yo!</h1>'
})
.state('special', {
url: '/special',
template: '<h1>So special!</h1>'
})
})
.run(function($rootScope){
//Now we can listen for $stateChangeError and use it to prevent
// the action if we detect our special error case.
$rootScope.$on('$stateChangeError', function handleStateChangeError(event, toState, toParams, fromState, fromParams, error) {
if (error && error.error === 'special_error_code') {
event.preventDefault();
this.$state.go('main', { returnState: toState.name, notify: false });
}
});
});
import * as _ from 'lodash';
export function stateProviderDecorator($stateProvider): void {
'use strict';
let originalStateFunction = $stateProvider.state;
$stateProvider.state = function (state, config): any {
//
// The config.someOptOutProperty allows you to prevent this
// code from running under certain circumstances. For instance
// if you are checking security, you might want to provide
// a way to allow "anonymous" routes, etc...
//
if (angular.isDefined(config) && !config.someOptOutProperty) {
//Make sure we only augment the existing resolve
// and don't overwrite anything.
_.defaults(config.resolve || (config.resolve = {}), {
/*@ngInject*/
someSpecialCheck: function userSessionSecurityCheck($q, specialCheckService){
let def = $q.defer();
specialCheckService.shouldIDoThis()
.then(result => {
if (result.data === 'some favorable condition') {
def.resolve(result.data);
}
else{
def.reject({
error: 'special_error_code'
});
}
});
return def.promise;
}
});
}
// *** IMPORTANT ***
//
//This is the important part, we have to make sure
// that the original function get's called.
//We merely want to intercept the state and augment
// it before passing it along.
return originalStateFunction.apply(this, arguments);
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment