Saturday 9 January 2016

Use Promise and service together in Angular

Use Promise and service together in Angular
To provide a service which stores some basic data retrieved from the backend via $http, then I only need to fetch those data once

var load = function() {
   return $http.get(...).then(function(data) {
       return data.user; 
   });
};

module.factory("userProvider", function() {
    var user;
    var getUser = function() {
        if(!user) {
            load().then(function(data) {
               user = data;
           });
        }
        return user;
    };
    return {
        getUser : getUser
    }
});

module.controller("UserController", ["userProvider", function UserController("userProvider") {
    var user = userProvider.getUser();
    // do something with user
}]);

The problem is that the promise chain ends in userProvider but not in controller, so the user is undefined the first time I use this controller since the data has not been returned.

The solution is

module.factory("userProvider", function($q) {
  var user,
      getUser = function() {
    var deferred = $q.defer();
    if(!user) {
      getUser().then(function(data) {
        user = data;
        deferred.resolve(user);
      });
    } else {
      deferred.resolve(user);
    }

    return deferred.promise;
  };

  return {
    getUser : getUser
  };
});
It's a bit of an overhead to create your own promise, angular's $http creates one for you anyway. What you're looking for is caching and http can handle it for you by passing cache:true to the service call.
So you can simply do something like this:
 module.factory("userProvider", function() {
   var getUser = function() {
   return $http.get(..., {cache:true}).then(function(data) {
       return data.user; 
   });

   return {
       getUser : getUser
   }
});















Angularjs Training | Angular.js Course | Angularjs Online Training | Angularjs Training in Chennai | AngularJS Interview Questions