Skip to content

Instantly share code, notes, and snippets.

@masimplo
Last active October 6, 2015 01:20
Show Gist options
  • Save masimplo/324e77a2dd20fb4aa227 to your computer and use it in GitHub Desktop.
Save masimplo/324e77a2dd20fb4aa227 to your computer and use it in GitHub Desktop.
Decorating $http service to support url interpolation
function httpDecorator($delegate: ng.IHttpService) {
var $http = $delegate;
var wrapper = () => {
// interpolate the url
var config = arguments[0];
config.url = interpolateUrl(config.url, config.params, config.data);
return $http.apply($http, arguments);
};
// $http has convenience methods such as $http.get() that we have
// to pass through as well.
Object.keys($http).filter(key => (typeof $http[key] === 'function')).forEach(key => {
wrapper[key] = () => {
// interpolate the url
arguments[0] = interpolateUrl(arguments[0], arguments[1].params, arguments[1].data);
return $http[key].apply($http, arguments);
};
});
// the $http service also has object properties that need to be copied (eg. defaults)
Object.keys($http).filter(key => (typeof $http[key] === 'object')).forEach(key => {
wrapper[key] = $http[key];
});
return wrapper;
}
httpDecorator.$inject = ['$delegate'];
// register the decorator on the loaded module
mainModule.config([
'$provide', $provide => {
$provide.decorator('$http', httpDecorator);
}
]);
// Code beyond this point adapted from: https://gist.github.com/bennadel/11178024/
// I move values from the params and data arguments into the URL where
// there is a match for labels. When the match occurs, the key-value
// pairs are removed from the parent object and merged into the string
// value of the URL.
function interpolateUrl(url, params, data) {
// Make sure we have an object to work with - makes the rest of the
// logic easier.
params = (params || {});
data = (data || {});
// Strip out the delimiter fluff that is only there for readability
// of the optional label paths.
url = url.replace(/(\(\s*|\s*\)|\s*\|\s*)/g, "");
// Replace each label in the URL (ex, :userID).
url = url.replace(
/:([a-z]\w*)/gi,
($0, label) => {
// NOTE: Giving "data" precedence over "params".
var val = popFirstKey(data, params, label);
return val !== null && val !== undefined ? val : '';
}
);
// Strip out any repeating slashes (but NOT the http:// version).
url = url.replace(/(^|[^:])[\/]{2,}/g, "$1/");
// Strip out any trailing slash.
url = url.replace(/\/+$/i, "");
return (url);
}
// I take 1..N objects and a key and perform a popKey() action on the
// first object that contains the given key. If other objects in the list
// also have the key, they are ignored.
function popFirstKey(object1, object2, objectN) {
// Convert the arguments list into a true array so we can easily
// pluck values from either end.
var objects = Array.prototype.slice.call(arguments);
// The key will always be the last item in the argument collection.
var key = objects.pop();
var object = null;
// Iterate over the arguments, looking for the first object that
// contains a reference to the given key.
while (object = objects.shift()) {
if (object.hasOwnProperty(key)) {
return (popKey(object, key));
}
}
}
// I delete the key from the given object and return the value.
function popKey(object, key) {
var value = object[key];
delete (object[key]);
return (value);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment