randomguy04 randomguy04 - 1 month ago 6
AngularJS Question

Angular - Use scope Variable in Service url

Currently I'd like to get data from an API, sending some search parameters using an AngularJS service. In my ng-model I have a variable called search, and I would like to use that variable as a parameter to the API URL.

My first (unsuccessful) approach was to use the $scope.search variable directly inside the service:

$http.get('http://www.omdbapi.com/?s='+ $scope.search +'&type=series&r=json').then(function(data){
deferred.resolve(data);
});


I've read that passing the $scope to the service is not possible (and shouldn't be done anyway), so how can I use the scope variable as a parameter in the service, also, is there a cleaner way to set the paramaters other than adding the string
myUrl + search
?

full code:

myApp.service('showsService', function($http, $q){
var deferred = $q.defer(); //promise to say 'im going to do this later'
$http.get('http://www.omdbapi.com/?s=sherlock&type=series&r=json').then(function(data){
deferred.resolve(data);
});
this.getShows = function(){
return deferred.promise;
}
});

myApp.controller("showsController", function($scope, showsService){
$scope.$watch('search', function() {
fetch();
});

function fetch(){
var promise = showsService.getShows();
promise.then(function(data){
$scope.showsResult = data.data.Search; //using the name than comes back from the API
});
}
});

Answer

Simply pass search as an argument to the service function:

myApp.service('showsService', function($http){
    this.getShows = function(search){
        var url = 'http://www.omdbapi.com/s='+search+'&type=series&r=json';
        var promise = $http.get(url);
        return promise;
    };
});

Then in the controller:

myApp.controller("showsController", function($scope, showsService){
   $scope.$watch('search', function(value) {
      fetch(value);
   });

   function fetch(search){
       var promise = showsService.getShows(search);
       promise.then(function(response){
           $scope.showsResult = response.data.Search;
       });
    };
});

There is no need to manufacture a promise with $q.defer as the $http service already returns a promise.


Update

The $http service is able to serialize parameters:

myApp.service('showsService', function($http){
    this.getShows = function(search){
        //var url = 'http://www.omdbapi.com/s='+search+'&type=series&r=json';
        var url = 'http://www.omdbapi.com/'
        var config = { 
            params: { 
                s: search,
                type: 'series',
                r: 'json'
            }
        };
        var promise = $http.get(url, config);
        return promise;
    };
});