Angular $q synchronous .then

attach .then handler after the promise was created

by Kyrylo Slatin

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.1/angular-resource.js"></script>
<div ng-controller="ctrl">
    <p>
        <button ng-click="doA()">Do A</button>
        <button ng-click="doB()">Do B</button>
        <button ng-click="doC()">Do C</button>
    </p>
    a:{{a}}<br>
    b:{{b}}
    <div id="messages"></div>
</div>

JavaScript

angular.module('app', ['ngResource']);
angular.module('app').controller('ctrl', function ($scope, $q, $timeout) {
    $scope.a = 'a';
    $scope.b = 'b';
    console.log('init');
    function log(message) {
        console.log(message);
        var d = document.getElementById('messages');
        d.innerHTML += JSON.stringify(message) + '<br>';
    }
    $scope.pending = 'c';
    $scope.next = function () {
        var result = $scope.pending;
        $scope.pending = String.fromCharCode($scope.pending.charCodeAt(0) + 1);;
        return result;
    };
    $scope.doA = function () {
        var d = $q.defer();
        log('Starting 5 sec timeout to assign a = b');
        $timeout(function(){
            $scope.a = $scope.b;
            log('Assigning a = b');
            $scope.$apply();
            d.resolve();
        }, 5000);
        $scope.promise = d.promise;
    };
    $scope.doB = function () {
        function assign(){
            var d = $q.defer();
            var delay = Math.random()*1000 >>> 0; 
            log('Starting ' + delay +  ' ms timeout to assign b = next()');
            $timeout(function(){
                $scope.b = $scope.next();
                log('Assigning b = next() //'+ $scope.b);
                d.resolve();
            }, delay);
            return d.promise;
        }
        if($scope.promise){
           log('Chaining operation b = next()');
           $scope.promise = $scope.promise.then(assign); 
        }else{
           assign(); 
        }
    }
    $scope.doC = function () {
        function assign(){
            log('Assigning a = a + a');
            $scope.a = $scope.a + $scope.a;
        }
        if($scope.promise){
           log('Chaining operation a = a + a');
           $scope.promise = $scope.promise.then(assign); 
        }else{
           assign(); 
        }
    }
});
angular.bootstrap(document, ['app']);