$timeout $q


Using AngularJS promises to perform
DOM manipulation at the right time




Q: Have you ever used a timeout to wait for DOM elements to finish loading?


An example...

directive('focus', function($timeout){
    return {
        restrict: 'A',
        scope: {
            'focus': '=focus'
        },
        link: function(scope, elem){
            scope.$watch('focus', function(val){
                if (val)
                    elem.focus();
                else
                    elem.blur();
            });
        }
    }
})


$timeout with 0ms

directive('focus', function($timeout){
    return {
        restrict: 'A',
        scope: {
            'focus': '=focus'
        },
        link: function(scope, elem){
            scope.$watch('focus', function(val){
                if (val)
                    $timeout(function(){ elem.focus(); });
                else
                    $timeout(function(){ elem.blur(); });
            });
        }
    }
})


You think you need it, but you don't.

Before we jump into $q...

Angular's Digest Cycle


$timeout (0ms) is called in the next available Event Queue.
This may cause unintended flickering and is not recommended.

$evalAsync

is called before the DOM renders, in the same $digest loop.

directive('focus', function($timeout){
    return {
        restrict: 'A',
        scope: {
            'focus': '=focus'
        },
        link: function(scope, elem){
            scope.$watch('focus', function(val){
                if (val)
                    $evalAsync(function(){ elem.focus(); });
                else
                    $evalAsync(function(){ elem.blur(); });
            });
        }
    }
})

Code Examples!!

What are you looking at?


  1. First, the desired result, accomplished via $q.
  2. Rewind. Unsatisfactory version with $timeout.
  3. Improve the select directive with a promise.
`


ng-Promises in action 

By Curt Kirkhoff

ng-Promises in action 

  • 691