henrik242 henrik242 - 1 month ago 8
AngularJS Question

How to store data from http service in angular factory

I would like to store the value from /api/login.json globally using a service, but I think I have some sort of timing issue. The console.log statement in the controller tells me that the scope.login object is undefined.

What am I missing?

Thanks!

Factory service:

myApp.factory('LoginFactory', ['$http', function($http){

this.data;
$http.get('/api/login.json').success(function(data) {
this.data = data;
});

return {
getData : function(){
return this.data;
}
}
}]);


Controller:

myApp.controller('AccountsCtrl', ['$scope', 'Accounts', 'LoginFactory', function($scope, Accounts, LoginFactory){
$scope.login = LoginFactory.getData();
console.log('$scope.login: %o', $scope.login);
$scope.accounts = Accounts.index();

}]);

Answer

you should probably avoid use of the this keyword in this context. better just to declare a new variable.

myApp.factory('LoginFactory', ['$http', function ($http) {
    var data;
    $http.get('/api/login.json').success(function (d) {
        data = d;
    });
    return {
        getData: function () {
            return data;
        }
    };
}]);

you will still have a race issue though, so i would also recommend either promise chaining

myApp.factory('LoginFactory', ['$http', function ($http) {
    var promise = $http.get('/api/login.json');
    return {
        getData: function (callback) {
            promise.success(callback);
        }
    };
}]);

or even a conditional get

myApp.factory('LoginFactory', ['$http', function ($http) {
    var data;
    return {
        getData: function (callback) {
            if(data) {
                callback(data);
            } else {
                $http.get('/api/login.json').success(function(d) {
                    callback(data = d);
                });
            }
        }
    };
}]);

The last two approaches require you to rewrite your controller though

myApp.controller('AccountsCtrl', ['$scope', 'Accounts', 'LoginFactory', function($scope, Accounts, LoginFactory){
  LoginFactory.getData(function(data) {
      $scope.login = data;
      console.log('$scope.login: %o', $scope.login);    
      $scope.accounts = Accounts.index(); //this might have to go here idk
  });
}]);