最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - AngualrJS $http returns undefined? - Stack Overflow

programmeradmin2浏览0评论

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.

发布评论

评论列表(0)

  1. 暂无评论