Richard Erdos
Richard Erdos

Reputation: 57

AngularJS $http request in a factory

I want to load a JSON file into a factory and then return its value.

Here's the code:

angular.module('getGuilds', [])
    .factory('getGuilds', getGuilds);

getGuilds.$inject = ['$http'];

function getGuilds($http){
    var obj = {content:null};

    $http.get('guild/guilds.json').success(function(data) {
        obj.content = data;
    });

    return obj;
}

The problem is that it only returns the object with the value of null, so it seems the $http.get doesn't change the value of the obj.content.

After this I did a little test:

    $http.get('guild/guilds.json').success(function(data) {
        obj.content = data;
    });

    console.log(obj)
    return obj;
}

It gave back this object insted of the JSON's array: {content:null}.

Then I put the console.log inside the $http.get request.

$http.get('guild/guilds.json').success(function(data) {
     obj.content = data;
     console.log(obj)
});

Guess what, it logged out the JSON file. Would somebody be so kind as to help me?

Upvotes: 1

Views: 1855

Answers (2)

Daniël Smink
Daniël Smink

Reputation: 368

This is because $http.get performs the get asynchronously. So at the point you were assigning the value, it wasn't available yet. You need to return the obj inside your success function changing your code like this should make it work:

// dataservice factory
angular
 .module('getGuilds', [])
 .factory('dataservice', dataservice);

dataservice.$inject = ['$http'];

function dataservice($http) {
    return {
      getGuilds: getGuilds
    };

    function getGuilds() {
       return $http.get('guild/guilds.json')
        .then(getGuildsComplete)
        .catch(getGuildsFailed);

       function getGuildsComplete(response) {
        return response.data;
       }

       function getGuildsFailed(error) {
         console.log('XHR Failed for getGuilds.' + error.data);
       }
    }
}

In your controller you would then call the dataservice:

dataservice.getGuilds()
  .then(function(data) {
    vm.guilds = data;
    return vm.guilds;
  });

Obviously the controller requires more code to actually work. But this should give you enough info to solve your issue.

Upvotes: 2

danh
danh

Reputation: 62686

$http.get performs the get asynchronously. The code that appears after the success block in the source runs before the code within the success block. So it's behaving just as expected: on your first attempt, you're logging the results of an unfinished request.

Upvotes: 3

Related Questions