callmekatootie
callmekatootie

Reputation: 11228

How to get data from service - data that will be fetched with a delay

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?

Upvotes: 1

Views: 2494

Answers (2)

Mathew Berg
Mathew Berg

Reputation: 28750

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.

Upvotes: 1

DarkLeafyGreen
DarkLeafyGreen

Reputation: 70406

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.

Upvotes: 1

Related Questions