Skip to content

Instantly share code, notes, and snippets.

@nicolashery
Last active February 9, 2017 11:31
Show Gist options
  • Select an option

  • Save nicolashery/6185327 to your computer and use it in GitHub Desktop.

Select an option

Save nicolashery/6185327 to your computer and use it in GitHub Desktop.
deferred.resolve() (using AngularJS' $q) and $rootScope.$apply() in async function outside of Angular
// Resolving a deferred created by AngularJS' $q, in an async function outside of Angular (ex: setTimeout)
//
// See:
// https://github.com/angular/angular.js/wiki/When-to-use-$scope.$apply()
// http://stackoverflow.com/questions/16066170/angularjs-directives-change-scope-not-reflected-in-ui/16066306#16066306
// https://github.com/angular/angular.js/blob/master/src/ng/timeout.js
// Using AngularJS' $q (1.0.7)
function testDeferredAngularSync() {
var deferred = $q.defer();
deferred.promise.then(function(result) {
console.log('promise success');
}, function(error) {
console.log('promise error');
});
console.log('resolving deferred');
deferred.resolve();
}
// Works
testDeferredAngularSync();
// -> resolving deferred
// -> promise success
function testDeferredAngularAsyncBroken() {
var deferred = $q.defer();
deferred.promise.then(function(result) {
console.log('promise success');
}, function(error) {
console.log('promise error');
});
setTimeout(function() {
console.log('resolving deferred');
deferred.resolve();
}, 1000);
}
// Broken!
testDeferredAngularAsyncBroken();
// -> resolving deferred
function testDeferredAngularAsync() {
var deferred = $q.defer();
deferred.promise.then(function(result) {
console.log('promise success');
}, function(error) {
console.log('promise error');
});
setTimeout(function() {
console.log('resolving deferred');
deferred.resolve();
$rootScope.$apply();
}, 1000);
}
// Works
testDeferredAngularAsync();
// -> resolving deferred
// -> promise success
// Using Q (http://documentup.com/kriskowal/q/)
function testDeferredQAsync() {
var deferred = Q.defer();
deferred.promise.then(function(result) {
console.log('promise success');
}, function(error) {
console.log('promise error');
});
setTimeout(function() {
console.log('resolving deferred');
deferred.resolve();
}, 1000);
}
// Works
testDeferredQAsync();
// -> resolving deferred
// -> promise success
@nicolashery
Copy link
Author

A good note from @BinaryMuse on having the .then() declaration in an async function outside of AngularJS, also requires a call to scope.$apply(): http://jsfiddle.net/BinaryMuse/sCs2H/

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