2

Here is my service:

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;
        }); 
    }
}]);

and controller -

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

how to send data to the controlller using a $http service inside a custom service?

d.h.
  • 1,206
  • 1
  • 18
  • 33
Aditya Gupta
  • 79
  • 1
  • 3
  • 8

2 Answers2

3

Several problems are $http is asynchronous and your service method topTracks() doesn't return anything. Also you can't return inside success, there is nowhere to return to ... use then() instead

You need to return the promise from service and set the scope in a promise callback in controller

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);
    });

  }
]);
charlietfl
  • 170,828
  • 13
  • 121
  • 150
  • .log($scope.data) got error => angular.min.js:111 TypeError: Cannot read property 'then' of undefined – Aditya Gupta Mar 26 '16 at 14:37
  • Probably didn't do `return $http` in the service as per code shown in asnwer – charlietfl Mar 26 '16 at 14:38
  • http://stackoverflow.com/users/1175966/charlietfl I got this, thanks. tell me one thing in the controller, $scope.data is not available outer service. If I want , how? – Aditya Gupta Mar 26 '16 at 14:44
  • function($scope, trackService) { trackService.topTracks(10).then(function(data) { $scope.data = data; //console.log($scope.data); => OK }); ////console.log($scope.data); => undefined – Aditya Gupta Mar 26 '16 at 14:50
  • Oooooh ... big problem with `this` inside the service inside the `then()`. See updates using `self`. I should have noticed that before. It is not the same `this` inside any of the callbacks like `success` or `then` – charlietfl Mar 26 '16 at 14:52
  • Also troubleshoot service first ...then controller – charlietfl Mar 26 '16 at 14:54
  • Please help me, I want to use values of $scope.data into another controller. – Aditya Gupta Mar 26 '16 at 15:18
2

Inside your service you are making an asynchronous GET request. In order to let the controller catch that response, you need to return a promise. Here's an example using $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;
    }
}]);
Asaf David
  • 3,167
  • 2
  • 22
  • 38
  • 3
    This is an anti pattern using `$q` ... `$http` already returns promise and there is no need to create a new one – charlietfl Mar 26 '16 at 13:39
  • See: http://stackoverflow.com/questions/23803743/what-is-the-explicit-promise-construction-antipattern-and-how-do-i-avoid-it or https://github.com/petkaantonov/bluebird/wiki/Promise-anti-patterns – charlietfl Mar 26 '16 at 13:43
  • @charlietfl Thanks for the link and comment. I do have a question regarding this. What if you need to do some manipulation on the response before resolving? Just as in this example where he wants to store the response in the service + logg it. – Asaf David Mar 26 '16 at 13:50
  • Use `then()` the way I did. Can do any manipulation there. The return in a `then()` is available in the next `then()` in the chain. Note that `$http` docs show `success` as deprecated for this very reason – charlietfl Mar 26 '16 at 13:52
  • @charlietfl Thanks! Just tested it on my code... Good to learn. I will edit my answer and refer to your answer. – Asaf David Mar 26 '16 at 14:04