AngualrJS $http возвращает undefined?


Согласно AngularJS, мой $http вызов через службу от моего контроллера возвращается неопределенным?

В чем, по-видимому, здесь проблема? Я пытаюсь вернуть вызванные данные, но как только они передаются контроллеру, данные становятся неопределенными?

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>

Я понимаю, что $http, $q, и $resource все обещания возврата ,но я думал, что покрыл это.затем.

2 4

2 ответа:

Проблема может заключаться в том, что вы не returnиспользуете обещание, созданное $http.get в вашей функции dataService.getData. Другими словами, вы можете решить свою проблему undefined, изменив то, что у вас есть:

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

Если у вас было несколько вызовов $http.get внутри dataService.getData, Вот как вы могли бы их обработать.

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

Гораздо более чистым способом, однако, было бы использовать $q.all

.service('dataService', ['$http', '$q', function($http, $q) {
    this.getData = function() {
        var combinedData, promises;
        combinedData = {};
        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;
        });
    };
}]);

Ваша проблема заключается в том, что вы не возвращаете обещание, но, как вы заявили в посте @maxenglander, у вас может быть несколько вызовов http, что означает, что вы должны начать создавать и разрешать свое собственное обещание с помощью $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>>;
            });
}];

Или если у вас есть несколько http-вызовов и вам нужно выполнить какую-то комбинационную работу, вы можете сделать что-то $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>>;
       });
}];

Тогда в вашем контроллере вам нужно будет сделать:

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

Что это позволяет в вашей службе теперь вы можете делать сложные вызовы, такие как, скажем, вызов двух веб-сервисов внутри и ждать, пока они оба не будут завершены, а затем решить обещание. То, что я пытаюсь выразить здесь, заключается в том, что вам не нужно возвращать обещание, предоставленное $http.получить функцию, но поскольку вы выполняете асинхронное действие, вам нужно вернуть некоторое обещание, которое будет позже выполнено и выполнено.