Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is this factory returning a $$state object instead of response.data?

So I have a collection of objects in the server I want to populate an ng-repeat when the page loads.

I had a made a factory which fetched the list from a resource on the server, like so:

  app.factory('objectArray', ['$http', function($http) {
      // This is returning a $$state object
      // instead of response.data...
      return $http.post('/get_collection').then(function(response) {
          console.log(response.data);
          return response.data;
      });
  }]);

I've had this code work before when using ui-router and the resolve property in the state declaration. However when injecting this factory directly into my controller, instead of getting response.data I am getting a $$state object.

My controller looks like this:

 app.controller('applicationController', ['$scope', 'objectArray', function($scope, objectArray) {
     $scope.array = objectArray;
     console.log($scope.array);
 }]);
like image 387
Alex Turner Avatar asked Nov 21 '15 13:11

Alex Turner


2 Answers

What the $http service returns (and thus the objectArray service is) is called a promise. You can access the actual data by registering a callback function that will be called when the data is available, i.e. when the response to the http request comes back from the server:

objectArray.then(function(data) {
    $scope.array = data;
});

The reason you directly have access to the data when using resolve is that the router, when the resolve function returns a promise, waits for the promise to be resolved. And only then, it extracts the data from the promise and injects the data into the controller.

To better understand promises, you could read the following article (and its sequel).

like image 59
JB Nizet Avatar answered Oct 25 '22 13:10

JB Nizet


As @JB Nizet noticed, you code is fine, just resolve it in controller Here's working demo

angular.module('app', []);
angular.module('app').factory('objectArray', ['$http', function($http) {
  // This is returning a $$state object
  // instead of response.data...
  ////// changed request type and url for the sake of example
  return $http.get('http://jsonplaceholder.typicode.com/posts/1')
.then(function(response) {
  console.log(response.data);
  return response.data;
});
}]);
angular.module('app').controller('applicationController', ['$scope', 'objectArray', function($scope, objectArray) { 
  //////resolve it here
  objectArray.then(function(successResponse){
    $scope.array = successResponse;
    console.log($scope.array);
  });
}]);
angular.bootstrap(document.body, ['app']);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-controller="applicationController">
  <h5>Hello {{array.title}}</h5>
</div>
like image 29
Medet Tleukabiluly Avatar answered Oct 25 '22 13:10

Medet Tleukabiluly