Skip to content

Instantly share code, notes, and snippets.

@clarabstract
Last active December 20, 2015 06:19
Show Gist options
  • Select an option

  • Save clarabstract/6085139 to your computer and use it in GitHub Desktop.

Select an option

Save clarabstract/6085139 to your computer and use it in GitHub Desktop.
Convert callback-based async functions to angular promises.
/*
Call a non-angular, async function that takes callback (and optional
error) arguments via a $q.defer() object and returns an angular
compatible promise.
For example:
somethingAsync(arg1, arg2, successHandler, failureHandler)
As a promise:
var promise = promiseCallback(somethingAsync, arg1, arg2);
This can be assigned directly to a scope variable (which will
update in the tempalte as expected):
$scope.asyncAnswer = promise;
Or collected together with other promises;
$scope.severalAnswers = $q.all([promise, promise2, promise3]);
... or chained using .then() or whatever else :)
More examples here: http://jsfiddle.net/hWW7q/
*/
function promiseCallback(fn) {
var _aps = Array.prototype.slice;
var args = _aps.call(arguments, 1);
var q = $q.defer();
args.push(function (arg) {
if( arguments.length > 1 ) arg = _aps.call(arguments,0);
$scope.$apply(function(){
q.resolve(arg);
});
});
args.push(function(arg) {
if( arguments.length > 1 ) arg = _aps.call(arguments,0);
$scope.$apply(function(arg){
q.reject(arg);
});
});
fn.apply(this, args);
return q.promise;
}
@clarabstract
Copy link
Author

Turns out .resolve() doesn't actually do more then one value, but since this is meant to plug into 3rd party libraries that can and often do pass more then one value to their callback, I added that ugly arguments.length sniffing to pass such cases on as arrays.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment