deferred in AngularJS

Mechanism of deferred objects, or if to be more precise the idea of deferred objects has been added to AngularJS from the library Q of Chris Cowan. Its essence lies in the fact that if a function can return a value or exception without blocking, it returns Promice object, which is an observer of the result of execution. Once a result is obtained or exception was raised, Deferred object notifies the observer.

Quite often, before loading of the controller, controller needs to get data for its activities. Speaking of data acquisition, I mean data receival hich can last undefined amount of time. The most frequent case - is to receive data from a server application. To solve this problem we need to pass resolve parameter to $routeProvider when configuring the routing of application. Resolve is an object which indicates the dependency for controller. Once all the dependencies are resolved, they are placed in the controller, after which there is a further initialization controller.

See the code for illustration:

angular.module('shopcat', ['shopcatFilters', 'shopcatServices', 'shopcatDirectives']).
  config(['$routeProvider', function ($routeProvider) {
      $routeProvider.
        when('/shops', {
            templateUrl: 'partials/shop-list.html',
            controller: ShopListCtrl,
            resolve: ShopListCtrl.resolve
        }).
        when('/shops/:shopId', {
            templateUrl: 'partials/shop-detail.html',
            controller: ShopDetailCtrl,
            resolve: PhoneDetailCtrl.resolve
        }).
        otherwise({ redirectTo: '/shops' });
  }]);
 
 
function ShopListCtrl($scope, Shops) {
    $scope.Shops = Shops;
    $scope.orderProp = 'name';
}
 
ShopListCtrl.resolve = {
    Shops: function (Shop, $q) {
        var deferred = $q.defer();
        //execute request for data receiving
        //deferred.resolve() if successful execute deffered.resolve
        //deferred.reject() if error execute deferred.reject()
        Shop.query(function (successData) {
            deferred.resolve(successData);
        }, function (errorData) {
            deferred.reject();
        });
        return deferred.promise;
    },
    delay: function ($q, $defer) {
        var delay = $q.defer();
        $defer(delay.resolve, 1000);
        return delay.promise;
    }
}

In demostrated example $q.defer() creates instance of object Defer. That object has two methods one for receving value ( deferred.resolve(val) ) and returning of refusal by reason, which is provided by deferred.reject(reason). Methods resolve and reject are called in callback methods. Calling of those methods happens in case of successful receival of data or in case of error. As soon as all Deferred objects are executed, their results will go to controller, and then will happen event of route changing and we will be able to make different actions with data inside of the controller.

No Comments

Add a Comment