Sign up ×
Stack Overflow is a community of 4.7 million programmers, just like you, helping each other. Join them; it only takes a minute:

I have a factory which provides me a promise when getting a json file :

myapp.factory('topAuthorsFactory', function($http, $q) {
    var factory = {
        topAuthorsList: false,
        getList: function() {
            var deffered = $q.defer();
            $http.get('../../data/top_10_authors.json')
                .success(function(data, status) {
                    factory.topAuthorsList = data;
                }).error(function(data, status) {
                    deffered.reject('There was an error getting data');
                });
            return deffered.promise;
        }
    };
    return factory;
});

and in my controller I want to display the content of the json file on my console as the following :

myapp.controller('topAuthorsController', function($scope, topAuthorsFactory) {


  $scope.listAuthors = topAuthorsFactory.getList().then(function(topAuthorsList) {

      $scope.listAuthors = topAuthorsList;
      console.log('Testing...');

  }, function(msg) {
    alert(msg);
  });

  console.log($scope.listAuthors);
    }

but in my console I'm getting this :

enter image description here

so how can I solve this ? and why I dont see the message "testing..." in console ?

share|improve this question
up vote 1 down vote accepted

You should resolve promise when you received response.

deferred.resolve(data)

Ideally you shouldn't follow the approach by which you are doing, creating new promise is considered as anti-pattern while you are dealing with $http.get which already return promise itself, you could utilize that promise. So basically you need to clean up your factory. By returning the $http.get object & .then function over it, (also .success & .error methods are deprecated). 1st function of then will get call when data received & otherwise the error function will get call. Basically for resolving or rejection promise you need to return data from promise, which will call subsequent .then function of caller method.

Factory

myapp.factory('topAuthorsFactory', function($http) {
  var factory = {
    topAuthorsList: false,
    getList: function() {
      //returning promise
      return $http.get('../../data/top_10_authors.json')
        .then(function(response) {
           var data = response.data;
           factory.topAuthorsList = data;
           //returning data to resolving promise
           return data;
        }, function(error) {
            return 'There was an error getting data';
        });
    }
  };
  return factory;
});

Edit

Basically you have assigned factory method call topAuthorsFactory.getList() to $scope.listAuthors method which is not required here, and then you are printing $scope.listAuthors variable which will obviously have promise object. So you should remove that assignment, & $scope.listAuthors value will be assigned from the .then function.

Controller

//remove $scope.listAuthors assignment which is incorrect.
topAuthorsFactory.getList().then(function(topAuthorsList) {
   $scope.listAuthors = topAuthorsList;
   console.log('Testing...');

}, function(msg) {
    alert(msg);
});

its asynchronous which will evaluate its function when async call get completed..the console.log statement

share|improve this answer
    
Thank you for your help I changed my factory to use the promise which is returns by the get method as you said, but I console I'm still getting that Promise object and I want to get the content of the json file printed in the console – Aimad MAJDOU Dec 12 '15 at 20:02
    
@AimadMAJDOU see you are confused with async call & how it works.. you could not get value of $scope.listAuthors before ajax gets completed..you need to place that console.log factory method call .then function..also need to remove unneccessary assignment while calling topAuthorsFactory.getList() method..Look at the updated answer for more detailed version. – Pankaj Parkar Dec 12 '15 at 20:05

Try this:

.success(function(data, status) {
    factory.topAuthorsList = data;
    deffered.resolve(data);
}).error(function(data, status) {
    deffered.reject('There was an error getting data');
});

You have to resolve the promise to get the data.

share|improve this answer

The first problem is that you log the promise itself immediately, and not it's resolution value. The second is that you don't even resolve the returned promise in getList. Try this instead:

getList: function() {
    return $http.get('../../data/top_10_authors.json').then(function(response) {
        return response.data;
    }, function() {
        throw 'There was an error getting data';
    });
}

// ...

$scope.listAuthors = null;
topAuthorsFactory.getList().then(function(topAuthorsList) {
    $scope.listAuthors = topAuthorsList;
    console.log('Testing...');
    console.log($scope.listAuthors);
}, function(msg) {
    alert(msg);
});

I noticed you used the explicit promise construction antipattern when using $http. $http already returns a promise, and that is favoured over success and error callbacks. I improved your getList function to employ promise chaining.

You can find some tutorial on using promises:

share|improve this answer
    
Thanks for you answer I did as you said and I worked with the promise from the $http.get function, but in console I get Null, from which I understand that the code inside the then method didn't change the $scope.listAuthors variable (I tried to log the topAuthorsList variable inside the then function and I got the json file printed on the console) how can I solve this ? – Aimad MAJDOU Dec 12 '15 at 20:13
    
@AimadMAJDOU The callback function in then is called when the promise resolves. That always happens later than the promise creation. You have to wait for the callback and use the value in the callback function. That's how promises work. Promise means that a value will be available later inside a callback. – hege_hegedus Dec 12 '15 at 20:18

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.