23

I'm trying AngularJS for the first time. I'm getting JSON data from a http-get request using a factory, but the object is returned empty, before the ajax-request is done.

Factory:

myDemo.factory('photosFactory', function($http) {
    var photos = [];

    var factory = {};

    factory.getPhotos = function() {
        $http({
            url: 'content/test_data.json',
            method: 'GET'
        }).success(function(data, status, headers, config) {
            photos = data;
            return photos;
        });
    };
    return factory;
});

Controller:

controllers.AppCtrl = function($scope, $location, $http, photosFactory) {
    $scope.photos = [];
    init();
    function init() {
        $scope.photos = photosFactory.getPhotos();
    }
};

This is what I've come up with. When the controller set $scope.photos, the value is empty as if it returns the photos array before it get populated with the ajax response.

3 Answers 3

55

You should modify your code to return a promise and use the value in controller pls see dummy modified code

myDemo.factory('photosFactory', function($http) {
 return{
    getPhotos : function() {
        return $http({
            url: 'content/test_data.json',
            method: 'GET'
        })
    }
 }
});

and controller -

controllers.AppCtrl = function($scope, $location, $http, photosFactory) {
    $scope.photos = [];
    photosFactory.getPhotos().success(function(data){
       $scope.photos=data;
   });
};
Sign up to request clarification or add additional context in comments.

1 Comment

can i use this for post method?
26

Using the q promise library means your success function can stay in your service:

app.factory('Data', function ($http, $q) {
    return {
        ajaxItems: function () {
            var deferred = $q.defer();
            $http({ method: "POST", url: "/Home/GetSearchResults" })
                .success(function (data, status, headers, config) {
                    deferred.resolve(data);
                }).error(function (data, status, headers, config) {
                    deferred.reject(status);
                });
            return deferred.promise;
        }
    }
});

app.controller('ResultsCtrl', ['$scope', 'Data', function ($scope, Data) {
    $scope.get = function () {
        $scope.items = Data.ajaxItems();
        //the model returns a promise and THEN items
        $scope.items.then(function (items) {
            $scope.items = items;
        }, function (status) {
            console.log(status);
        });
    };
}]);

2 Comments

Thanks for this. I think this is the best way of doing it. it keeps the controller lean.
How can we handle the error? What would be the value of items when there is an error?
7

Using the $resource will let you achieve what you want, plus give you much more control compared to $http

(Do not forget to include ngResrouce as a dependency to your app.)

myDemo.factory('photosFactory', function($resource) {
    var factory = {};

    factory.getPhotos = $resource('content/test_data.json', {}, {
        'query': {method: 'GET', isArray: true}
    });
    return factory;
});

controllers.AppCtrl = function($scope, $location, $http, photosFactory) {
    $scope.photos = [];
    init();
    function init() {
        $scope.photos = photosFactory.getPhotos.query();
    }
};

2 Comments

What is the advantage of doing this compared to @Ajay beniwal answer?
When using $resource each of your photos are AngularJs resource objects that contain methods like $save $delete, it makes using Restful api a lot easier.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.