CodyBugstein
CodyBugstein

Reputation: 23352

Angular service to get JSON from local file not working

I tried creating a service that will get data from a local JSON file, but it's not working, and there's no explanation why not.

The plunkr is here. Here's my code for the service:

webTestApp.factory('webtest', function($q, $timeout, $http) {
    var Webtest = {
        fetch: function(callback) {
            var ret = function() {
                $http.get('webtest.json').success(function(data) {
                    return data;
                });
            };

            return ret();
        }
    };
    return Webtest;
});

The Plunkr above is exactly what I was doing in my project, but I forked another Plunkr where someone got the same sort of thing was working. I found it at this StackOverflow answer.

Here's a working version

webTestApp.factory('webtest', function($q, $timeout, $http) {
    var Webtest = {
        fetch: function(callback) {

            var deferred = $q.defer();

            $timeout(function() {
                $http.get('webtest.json').success(function(data) {
                    deferred.resolve(data);
                });
            }, 30);

            return deferred.promise;
        }
    };

    return Webtest;
});

My question is, why does my version (the first block) not work, but the second one does?

Upvotes: 0

Views: 994

Answers (1)

Shomz
Shomz

Reputation: 37711

You are overcomplicating it with the ret function. Here is a simplified version of your code where I simply return the promise that $http call returns: http://plnkr.co/edit/9VaqIuOVHyMI12Z0r3jm?p=preview

To get your version to work, your ret function needs to return something ($http is an async call, so it doesn't matter its success actually callback returns something):

        var ret = function() {
            return $http.get('webtest.json').success(function(data) {
      // this ^^ is the key
                return data;
            });
        };

Then, when the $http promise is resolved, the actual data content is in response.data, not just response (full response actually contains headers and other server call-related info). Here is your original version with those two fixes: http://plnkr.co/edit/mzsdTFWr3qAXGfizjRRC?p=preview

That second example you wrote works because it return a simple $q promise (that's why $scope.data works and $scope.data.data is not needed), but it represents an antipattern, so you should stick with your original approach (or use the simplified version I gave you in the first paragraph).

Upvotes: 1

Related Questions