admin管理员组

文章数量:1403461

According to AngularJS, my $http call through a service from my controller is returning undefined?

What seems to be the issue here? I am trying to return the data called, but once passed to the controller the data bees undefined?

JavaScript

var myStore = angular.module('myStore', [])

    .controller('StoreController', ['$scope', 'dataService', function ($scope,  dataService) {
      $scope.products = dataService.getData();
    }])

    .service('dataService', ['$http', function($http) {
      this.getData = function() {
        $http.get('assets/scripts/data/products.json')
              .then(function(data) {
                return data;
              });
      };
    }]);

HTML

<div class="content">
  <ul>
    <li ng-repeat="product in products.products">{{product.productName}}</li>
  </ul>
</div>

I understand that $http, $q, and $resource all return promises, but I thought I had covered that with .then.

According to AngularJS, my $http call through a service from my controller is returning undefined?

What seems to be the issue here? I am trying to return the data called, but once passed to the controller the data bees undefined?

JavaScript

var myStore = angular.module('myStore', [])

    .controller('StoreController', ['$scope', 'dataService', function ($scope,  dataService) {
      $scope.products = dataService.getData();
    }])

    .service('dataService', ['$http', function($http) {
      this.getData = function() {
        $http.get('assets/scripts/data/products.json')
              .then(function(data) {
                return data;
              });
      };
    }]);

HTML

<div class="content">
  <ul>
    <li ng-repeat="product in products.products">{{product.productName}}</li>
  </ul>
</div>

I understand that $http, $q, and $resource all return promises, but I thought I had covered that with .then.

Share Improve this question edited Apr 20, 2015 at 6:43 Arslan Ali 17.8k9 gold badges64 silver badges83 bronze badges asked Apr 20, 2015 at 3:04 Aaron BrewerAaron Brewer 3,67719 gold badges51 silver badges79 bronze badges 2
  • 2 getData() doesn't have a return statement of its own. The return data instead applies only to the callback, function(data). Though, $http is also asynchronous, meaning getData() doesn't wait for data to bee available -- How to return the response from an asynchronous call? Note especially the mentions of Promises (.then()-ables). – Jonathan Lonowski Commented Apr 20, 2015 at 3:09
  • Just add return this as the last line of the service, hope it will solve your problem – Ali Adravi Commented Oct 19, 2015 at 20:35
Add a ment  | 

2 Answers 2

Reset to default 5

The problem could be that you are not returning the promise created by $http.get in your dataService.getData function. In other words, you may solve your undefined issue by changing what you have to this:

.service('dataService', ['$http', function($http) {
    this.getData = function() { 
        return $http.get...
    };
}

If you had multiple calls to $http.get within dataService.getData, here is how you might handle them.

.service('dataService', ['$http', function($http) {
    this.getData = function() {
        var binedData, promise;
        binedData = {};
        promise = $http.get(<resource1>);
        promise.then(function (data1) {
            binedData['resource1Response'] = data1;
            return $http.get(<resource2>);
        });
        return promise.then(function (data2) {
            binedData['resource2Response'] = data2;
            return binedData;
        });
    };
}]);

A much cleaner way, however, would be to use $q.all

.service('dataService', ['$http', '$q', function($http, $q) {
    this.getData = function() {
        var binedData, promises;
        binedData = {};
        promises = $q.all([
            $http.get(<resource1>),
            $http.get(<resource2>)
        ]);
        return promises.then(function (allData) {
            console.log('resource1 response', allData[0]);
            console.log('resource2 response', allData[1]);
            return allData;
        });
    };
}]);

You're problem does lie in the fact that you are not returning a promise but as you stated in @maxenglander's post you may have multiple http calls involved which means you should start creating and resolving your own promise using $q:

.service('dataService', ['$http', '$q', function($http, $q) {
      return $http.get('assets/scripts/data/products.json')
          .then(function(data) {
            //possibly do work on data
             return <<mutated data>>;
            });
}];

or if you have multiple http calls and need to do some bination work you can do something $q.all:

.service('dataService', ['$http', '$q', function($http, $q) {
      var p1 = $http.get('assets/scripts/data/products.json');
      var p2 = $http.get('assets/scripts/data/products2.json');
      return $q.all([p1, p2]).then(function(result){
         //do some logic with p1 and p2's result
         return <<p1&p2s result>>;
       });
}];

then in your controller you will need to do:

.controller('StoreController', ['$scope', 'dataService', function ($scope,  dataService) {
     dataService.getData().then(function(result){
         $scope.products = result;
     });
}]);

What this allows in your service is now you can do plex calls like say call two webservices inside and wait till they are both plete then resolve the promise. What I'm trying to express here is that you don't need to return the promise provided by the $http.get function, but since you are doing an async action you DO need to return some promise that will be later fulfilled and acted on.

本文标签: javascriptAngualrJS http returns undefinedStack Overflow