I wrote this little code in a custom service in AngularJS.
In my service:
var deferred = $q.defer();
var promise = deferred.promise;
IMHO, @jessegavin 's decoration of $q is not perfect, it shouldn't return origin promise in success&error function. It will lose feature of flatten the callback pyramid.
And it can't split response data to success&error function $httpPromise dose.
for example
//can't do this..
somePromise.success(function(){
return $http.get(...)//another primise
}).success(function(data){
//data from $http.get..
})
Here is my version, it will recognize http response and will return the next promise. Make your own $q have the same behavior like $httpPromise
$provide.decorator('$q', function($delegate) {
function httpResponseWrapper(fn) {
return function(res) {
if (res.hasOwnProperty('data') && res.hasOwnProperty('status') && res.hasOwnProperty('headers') && res.hasOwnProperty('config') && res.hasOwnProperty('statusText')) {
return fn(res.data, res.status, res.headers, res.config, res.statusText);
} else {
return fn(res);
}
};
};
function decorator(promise) {
promise.success = function(fn) {
return decorator(promise.then(httpResponseWrapper(fn)));
};
promise.error = function(fn) {
return decorator(promise.then(null, httpResponseWrapper(fn)));
};
return promise;
};
var defer = $delegate.defer;
$delegate.defer = function() {
var deferred = defer();
decorator(deferred.promise);
return deferred;
};
return $delegate;
});