служба не возвращает данные контроллеру в angular

Вот мой сервис:

app.service('trackService', ['$http', function($http) {
    var data;
    this.topTracks = function(limit) {
        $http({
            method: 'GET',
            url: 'http://ws.audioscrobbler.com/2.0/?method=chart.gettoptracks',
            params: {api_key: 'e8452c5962aafbb3e87c66e4aaaf5cbf', format: 'json', limit: limit}
        }).success(function(result) {
            this.data = result.tracks; console.log(this.data); return this.data;
        }); 
    }
}]);

и контроллер -

app.controller('artistSongsCtrl', ['$scope', 'trackService', function($scope, trackService) {
    $scope.data = trackService.topTracks(10);
    //console.log($scope.data);
}]);

как отправить данные на контроллер с помощью службы $http внутри пользовательской службы?


person Aditya Gupta    schedule 26.03.2016    source источник


Ответы (2)


Несколько проблем: $http является асинхронным, а ваш метод службы topTracks() ничего не возвращает. Также нельзя вернуться внутрь success, возвращаться некуда... вместо этого используйте then()

Вам нужно вернуть обещание из службы и установить область действия в обратном вызове обещания в контроллере.

app.service('trackService', ['$http',
  function($http) {
    var data;
    var self = this;
    this.topTracks = function(limit) {
      return $http({
        method: 'GET',
        url: 'http://ws.audioscrobbler.com/2.0/?method=chart.gettoptracks',
        params: {
          api_key: 'e8452c5962aafbb3e87c66e4aaaf5cbf',
          format: 'json',
          limit: limit
        }
      }).then(function(result) {
        self.data = result.data.tracks;
        console.log(self.data);
        return self.data;
      });
    }
  }
]);

app.controller('artistSongsCtrl', ['$scope', 'trackService',
  function($scope, trackService) {
    trackService.topTracks(10).then(function(data) {
      $scope.data = data;
      //console.log($scope.data);
    });

  }
]);
person charlietfl    schedule 26.03.2016
comment
.log($scope.data) получил ошибку => angular.min.js: 111 TypeError: Невозможно прочитать свойство «тогда» неопределенного - person Aditya Gupta; 26.03.2016
comment
Вероятно, не сделал return $http в сервисе согласно коду, указанному в ответе. - person charlietfl; 26.03.2016
comment
stackoverflow.com/users/1175966/charlietfl Я понял, спасибо. подскажите одно в контроллере $scope.data недоступен внешний сервис. Если я хочу, то как? - person Aditya Gupta; 26.03.2016
comment
function($scope, trackService) { trackService.topTracks(10).then(function(data) { $scope.data = data; //console.log($scope.data); => OK }); ////console.log($scope.data); =› не определено - person Aditya Gupta; 26.03.2016
comment
Ооооо... большая проблема с this внутри сервиса внутри then(). Смотрите обновления, используя self. Я должен был заметить это раньше. Это не то же самое this внутри любого из обратных вызовов, таких как success или then - person charlietfl; 26.03.2016
comment
Также сначала устраните неполадки службы ... затем контроллера - person charlietfl; 26.03.2016
comment
Пожалуйста, помогите мне, я хочу использовать значения $scope.data в другом контроллере. - person Aditya Gupta; 26.03.2016

Внутри вашего сервиса вы делаете асинхронный запрос GET. Чтобы позволить контроллеру поймать этот ответ, вам нужно вернуть обещание. Вот пример использования $q:

app.service('trackService', ['$http', '$q', function($http, $q) {
    var data;
    this.topTracks = function(limit) {
        var d = $q.defer();
        $http({
            method: 'GET',
            url: 'http://ws.audioscrobbler.com/2.0/?method=chart.gettoptracks',
            params: {api_key: 'e8452c5962aafbb3e87c66e4aaaf5cbf', format: 'json', limit: limit}
        }).success(function(result) {
            this.data = result.tracks; 
            console.log(this.data); 
            d.resolve(this.data);
        }); 
     return d.promise;
    }
}]);
person Asaf David    schedule 26.03.2016
comment
Это анти-шаблон с использованием $q... $http уже возвращает обещание, и нет необходимости создавать новый. - person charlietfl; 26.03.2016
comment
@charlietfl Спасибо за ссылку и комментарий. У меня есть вопрос по этому поводу. Что делать, если вам нужно выполнить некоторые манипуляции с ответом перед разрешением? Так же, как в этом примере, где он хочет сохранить ответ в сервисе + зарегистрировать его. - person Asaf David; 26.03.2016
comment
Используйте then() так, как это сделал я. Там можно делать любые манипуляции. Возврат в then() доступен в следующем then() в цепочке. Обратите внимание, что $http документы показывают success как устаревшее именно по этой причине. - person charlietfl; 26.03.2016
comment
@charlietfl Спасибо! Только что проверил на своем коде... Приятно учиться. Я отредактирую свой ответ и обращусь к вашему ответу. - person Asaf David; 26.03.2016