1

I have the following service declared:

app.factory('data', ['$http', function ($http) {

        var dataRecords = {};

        //Retrieve the entries from the data file and categorize them according
        //to the information types located in the overview page
        $http.get('data.json')
            .success(function (records) {
                    //Fill the dataRecords variable
        });

        return {
            get: function () {
                return dataRecords;
            },
            setNew: function (newRecords) {
                dataRecords = newRecords;
            }
        };
    }]);

As can be seen, using $http I fetch the data from the data.json file. Now my issue is that when I call the get method of the data service, I get back empty records even though data.json is not empty.

As I understand, $http.get() will return the data with some delay and hence when I call get, it is still not filled and hence I get empty values.

How do I call the service and ensure that the data is filled when I am fetching it from the service?

callmekatootie
  • 10,989
  • 15
  • 69
  • 104

2 Answers2

1

You are doing it wrong. I think the correct way would be:

app.factory('MyService', ['$http', function ($http) {

    var dataRecords = {};

    return {
        get: function (success) {
            $http.get('data.json').success(success) {});
        }
    };
}]);

And call it

 MyService.get(function(response) {
      //on success
 });

So you want your service to be initialized with http.get. This is not an easy task. However there is already such question on SO: AngularJS : Initialize service with asynchronous data


However you also could do it this way:

app.factory('MyService', ['$http', function ($http) {

    var myService = {};

    myService.get = function () {
        return myService.records;
    }

    myService.load = function(){
        $http.get('data.json').success(function(response){
             myService.records = response;
             return myService.records;
        }) {});
    }

    return myService;
}]);

In controller:

if(typeof MyService.get() === 'undefined'){
    $scope.records = MyService.load();
}

Upon controller initialization the data will fetched be once.

Community
  • 1
  • 1
DarkLeafyGreen
  • 69,338
  • 131
  • 383
  • 601
  • But wouldn't `$http.get(..)` be called each time i call MyService.get()? I do'nt want to make repeated calls the fetch the data - only once when the application loads – callmekatootie May 26 '13 at 09:06
1

Going of @artowrkad's example, if you only want it to get it once and only once, just implement the logic to not get it again like so:

app.factory('MyService', ['$http', function ($http) {

    var dataRecords = false;

    return {
        get: function (successCallback) {
            if(!dataRecords){
                $http.get('data.json').success(function(data){
                    dataRecords = data;
                    successCallback(data);
                ));
            }
            else{
                successCallback(dataRecords);
            }
        }
    };
}]);

You can even improve it so that if it's running the $http.get while you make a second call to wait and then make the callback you need when it's finished.

Mathew Berg
  • 28,625
  • 11
  • 69
  • 90