2

I am trying to send data from my http service to my controller. The service correctly gets the data but it doesn't get sent to the controller.

Now, I am aware that the query is done asynchronously which is why I am trying to use $q.defer. I tried following the example provided by a similar question : AngularJS $http call in a Service, return resolved data, not promises , however it still doesn't work.

Here is my Service :

.service("builds", ['$http', '$q', function($http, $q) {
  var deferred = $q.defer();

  $http({
      method:'GET',
      url: '/builds',
      cache : true
  }).success(function(data) {
      deferred.resolve(data);
  }).error(function(msg){
      deferred.reject(msg);
  });
  console.log(deferred.promise);
  return deferred.promise;}]);

And here is my routeProvider

$routeProvider.
    when('/builds', {
        controller: ['$scope', 'buildsData', function ($scope, buildsData) {
            console.log("In routeprovider:" + buildsData);
            $scope.allBuilds = buildsData;
        }],
      template: '<build-list></build-list>',
      resolve: {
          buildsData: ['builds', function(builds){
              return builds;
          }]
      }
    })

And finally here is a snippet of my Controller :

var app = angular.
 module('buildList').
  component('buildList', {
   templateUrl: 'build-list/build-list.template.html',
    controller: function BuildListController($scope, $window,$location,$cookies, builds) {
     console.log($scope.allBuilds);
     $scope.league = $scope.allBuilds;
Community
  • 1
  • 1
Storm
  • 387
  • 1
  • 5
  • 18
  • you have to call service from the controller to get the data. create a metho d in service that encapsulates that logic and then call that method from ctrl. – Vishal Anand Aug 13 '16 at 06:03

2 Answers2

2

As @vishal says

You should create a method in service because generally a service may have many get and set methods ( I mean best practice).

create a function say getData

function getData()
{
  $http({
      method:'GET',
      url: '/builds',
      cache : true
  })
}

then you should be calling this method in controller

In the controller you should inject this service and then

builds.getData().then(function(s){
//result

},function(e){

//error
}
);
Pankaj Parkar
  • 134,766
  • 23
  • 234
  • 299
saiyan
  • 512
  • 6
  • 21
  • Thanks, I got it to work doing like you said. But there is a problem : The data is getting requested twice... Once as soon as the page loads (probably from my routeProvider triggering getBuilds()) and a 2nd time when I call getBuilds() in my controller. Should I not call getBuilds() in the routeProvider at all? That seemed like the logical thing to do but I dont seem to be using that data anywhere... – Storm Aug 13 '16 at 15:44
  • Update no2 : Sorry if this is getting lengthy. I removed the return builds.getBuilds() from my routeProvider resolve. Now my website loads instantly and the data is then populated 2-3 seconds later. Works great! – Storm Aug 13 '16 at 15:51
0

you shouldntt have

 controller: ['$scope', 'buildsData', function ($scope, buildsData) {
            console.log("In routeprovider:" + buildsData);
            $scope.allBuilds = buildsData;
        }],

and a controller in an other file:

You can directly do

 when('/builds', {
        controller: 'BuildListController'
      template: '<build-list></build-list>',
      resolve: {
          buildsData: ['builds', function(builds){
              return builds;
          }]
      }
    })

and then in your controller

$scope.allBuilds = buildsData;

Beside, if you want add some functions to it , your service should look,like this:

.service("builds", ['$http', '$q', function($http, $q) {

      var deferred = $q.defer();

    getbuilds: function(){
      $http({
          method:'GET',
          url: '/builds',
          cache : true
      }).success(function(data) {
          deferred.resolve(data);
      }).error(function(msg){
          deferred.reject(msg);
      });
      console.log(deferred.promise);
      return deferred.promise;}]);
    }
Dan M. CISSOKHO
  • 1,070
  • 1
  • 12
  • 27
  • I thought simply having $scope.allBuilds = buildsData; in the controller was not enough. Can I just call builds.getBuilds() or do I need a special function to make sure it waits to recieve the data before proceeding? – Storm Aug 13 '16 at 15:14
  • A service is not a function but ou could see it as a collection of functions. So you have to call it like @saiyan says – Dan M. CISSOKHO Aug 14 '16 at 13:30