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 ответа:
Проблема может заключаться в том, что вы не
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.получить функцию, но поскольку вы выполняете асинхронное действие, вам нужно вернуть некоторое обещание, которое будет позже выполнено и выполнено.