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?

2 Answers 2

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

  }
]);
Sign up to request clarification or add additional context in comments.

7 Comments

.log($scope.data) got error => angular.min.js:111 TypeError: Cannot read property 'then' of undefined
Probably didn't do return $http in the service as per code shown in asnwer
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?
function($scope, trackService) { trackService.topTracks(10).then(function(data) { $scope.data = data; //console.log($scope.data); => OK }); ////console.log($scope.data); => undefined
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
|
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;
    }
}]);

5 Comments

This is an anti pattern using $q ... $http already returns promise and there is no need to create a new one
@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.
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 Thanks! Just tested it on my code... Good to learn. I will edit my answer and refer to your answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.